#include "windows.h"
#include <conio.h>
#include <stdlib.h>
#include <fstream.h>
#include <io.h>
#include <string.h>
#include <stdio.h> void Create_ProcInfo(); // 建立进程调度需要的数据
void Display_ProcInfo(); // 显示当前系统全部进程的状态
void Scheduler_FF();
void Cpu_Sched();
void IO_Sched();
void NextRunProcess();
void DisData();
void DisResult(); int RunPoint; // 运行进程指针,-1时为没有运行进程
int WaitPoint; // 阻塞队列指针,-1时为没有阻塞进程
int ReadyPoint; // 就绪队列指针,-1时为没有就绪进程
long ClockNumber; // 系统时钟
int ProcNumber; // 系统中模拟产生的进程总数
int FinishedProc; // 系统中模拟产生的进程总数
int q=;//时间片 //进程信息结构
struct ProcStruct
{
int p_pid; // 进程的标识号
char p_state; // 进程的状态,C--运行 R--就绪 W--组塞 B--后备 F--完成
int p_rserial[]; // 模拟的进程执行的CPU和I/O时间数据序列,间隔存储,0项存储有效项数
int p_pos; // 当前进程运行到的序列位置
int p_starttime; // 进程建立时间
int p_endtime; // 进程运行结束时间
int p_cputime; // 当前运行时间段进程剩余的需要运行时间
int p_iotime; // 当前I/O时间段进程剩余的I/O时间
int p_next; // 进程控制块的链接指针
int p_excutetime; // 记录一次时间片内执行的时间
} proc[]; ////////////////////////////////////////////////////////////////////////////
//
// 随机生成进程数量和每个CPU--I/O时间数据序列,进程数量控制在5到10之间, //
// 数据序列控制在6到12之间,CPU和I/O的时间数据值在5到15的范围 //
//
//////////////////////////////////////////////////////////////////////////// void Create_ProcInfo(void )
{
int s,i,j; srand(GetTickCount()); // 初始化随机数队列的"种子"
ProcNumber=((float) rand() / ) * ; // 随机产生进程数量5~10 for(i=;i<ProcNumber;i++) // 生成进程的CPU--I/O时间数据序列
{
proc[i].p_pid=((float) rand() / ) * ;
proc[i].p_state='B'; // 初始都为后备状态 s=((float) rand() / ) * + ; // 产生的进程数据序列长度在6~12间
proc[i].p_rserial[]=s; // 第一项用于记录序列的长度
for(j=;j<=s;j++) // 生成时间数据序列
proc[i].p_rserial[j]=((float) rand() / ) * + ;
// 赋其他字段的值
proc[i].p_pos=;
proc[i].p_starttime=((float) rand() / ) *+; // 随机设定进程建立时间
proc[i].p_endtime=;
proc[i].p_cputime=proc[i].p_rserial[];
proc[i].p_iotime=proc[i].p_rserial[];
proc[i].p_next=-;
proc[i].p_excutetime=;
}
printf("\n---------------------------\n 建立了%2d 个进程数据序列\n\n", ProcNumber);
DisData();
printf("\nPress Any Key To Continue.......");
_getch() ;
return ;
} //////////////////////////////////////////////////////////////////////// // 显示系统当前状态 //////////////////////////////////////////////////////////////////////// void Display_ProcInfo(void)
{ int i,n; system("cls") ;
printf("时间片为%d",q);
printf("\n 当前系统模拟%2d 个进程的运行 时钟:%ld\n\n", ProcNumber,ClockNumber); printf(" 就绪指针=%d, 运行指针=%d, 阻塞指针=%d\n\n",ReadyPoint,RunPoint,WaitPoint );
if(RunPoint!= -)
{
printf(" 当前运行的进程 No.%d ID:%d\n", RunPoint,proc[RunPoint].p_pid);
printf(" %6d,%6d,%6d\n",proc[RunPoint].p_starttime,proc[RunPoint].p_rserial[proc[RunPoint].p_pos],proc[RunPoint].p_cputime);
printf("当前运行的进程执行的时间为%d",proc[RunPoint].p_excutetime);
printf("当前运行的进程执行的cpu时间为%d",proc[RunPoint].p_cputime);
}
else
printf(" 当前运行的进程ID:No Process Running !\n"); n=ReadyPoint;
printf("\n Ready Process ...... \n");
while(n!=-) // 显示就绪进程信息
{
printf(" No.%d ID:%5d,%6d,%6d,%6d\n",n,proc[n].p_pid,proc[n].p_starttime,proc[n].p_rserial[proc[n].p_pos],proc[n].p_cputime );
n=proc[n].p_next;
} n=WaitPoint;
printf("\n Waiting Process ...... \n");
while(n!=-) // 显示阻塞进程信息
{
printf(" No.%d ID:%5d,%6d,%6d,%6d\n",n,proc[n].p_pid,proc[n].p_starttime,proc[n].p_rserial[proc[n].p_pos],proc[n].p_iotime);
n=proc[n].p_next;
} printf("\n=================== 后备进程 ====================\n");
for(i=; i<ProcNumber; i++)
if (proc[i].p_state=='B')
printf(" No.%d ID:%5d,%6d\n",i,proc[i].p_pid,proc[i].p_starttime); printf("\n================ 已经完成的进程 =================\n");
for(i=; i<ProcNumber; i++)
if (proc[i].p_state=='F')
printf("No.%d ID:%5d,%6d,%6d\n",i,proc[i].p_pid,proc[i].p_starttime,proc[i].p_endtime); } //////////////////////////////////////////////////////////////////////// // 显示模拟执行的结果 ////////////////////////////////////////////////////////////////////////
void DisResult(void)
{ int i;
printf("\n---------------------------------\n");
for(i=; i<ProcNumber; i++)
{
printf("ID=%4d> %2d ",proc[i].p_pid ,proc[i].p_rserial[] );
printf("%4d,%4d",proc[i].p_starttime,proc[i].p_endtime);
printf("\n" );
}
} //////////////////////////////////////////////////////////////////////// // 显示进程数据序列 ////////////////////////////////////////////////////////////////////////
void DisData(void)
{ int i,j; for(i=; i<ProcNumber; i++)
{
printf("ID=%4d %2d > ",proc[i].p_pid ,proc[i].p_rserial[] );
for(j=; j<=proc[i].p_rserial[];j++)
printf("%4d",proc[i].p_rserial[j]);
printf("\n" );
}
}
//////////////////////////////////////////////////////////////////////// // 选择下一个可以运行的进程 ////////////////////////////////////////////////////////////////////////
void NextRunProcess(void)
{
if (ReadyPoint==-) { RunPoint = -; return;} // 就绪队列也没有等待的进程 proc[ReadyPoint].p_state ='C'; //ReadyPoint所指示的进程状态变为执行状态
RunPoint=ReadyPoint;
if( proc[ReadyPoint].p_excutetime==-)//进程为执行成功,接着上次的cpu时间执行
{
proc[ReadyPoint].p_excutetime=;
}
else
proc[ReadyPoint].p_cputime =proc[ReadyPoint].p_rserial[proc[ReadyPoint].p_pos] ;
ReadyPoint=proc[ReadyPoint].p_next;
proc[RunPoint].p_next = -; }
//////////////////////////////////////////////////////////////////////// // CPU调度 //////////////////////////////////////////////////////////////////////// void Cpu_Sched(void)
{
int n; if (RunPoint == -) // 没有进程在CPU上执行
{ NextRunProcess(); return; } proc[RunPoint].p_cputime--; // 进程CPU执行时间减少1个时钟单位
proc[RunPoint].p_excutetime++;
if((proc[RunPoint].p_cputime == &&proc[RunPoint].p_excutetime<=q))//若时间片未完,但进程已经结束
{
//printf("若时间片未完,但进程已经结束\n");
proc[RunPoint].p_excutetime=;//清空运行时间
// 进程完成本次CPU后的处理
if (proc[RunPoint].p_rserial[]==proc[RunPoint].p_pos) //进程全部序列执行完成
{
FinishedProc++;
proc[RunPoint].p_state ='F';
proc[RunPoint].p_endtime = ClockNumber;
RunPoint=-; //无进程执行
NextRunProcess();
}
else //进行IO操作,进入阻塞队列
{
proc[RunPoint].p_pos++;
proc[RunPoint].p_state ='W';
proc[RunPoint].p_iotime =proc[RunPoint].p_rserial[proc[RunPoint].p_pos];
printf("进入阻塞队列\n");
n=WaitPoint;
if(n == -) //是阻塞队列第一个I/O进程
WaitPoint=RunPoint;
else
{ do //放入阻塞队列第尾
{
if(proc[n].p_next == -)
{ proc[n].p_next = RunPoint;
break;
}
n=proc[n].p_next;
} while(n!=-) ;
}
RunPoint=-;
NextRunProcess();
}
return;
}
if(proc[RunPoint].p_cputime > &&proc[RunPoint].p_excutetime<q)//时间片未完 程序未执行结束 继续执行
{
//printf("时间片未完 程序未执行结束 继续执行\n");
return;
}
//{ printf("\n RunPoint=%d,ctime=%d",RunPoint,proc[RunPoint].p_cputime);getchar();return; }
if(proc[RunPoint].p_cputime > &&proc[RunPoint].p_excutetime==q)//时间片完,但是程序未执行完 放到就绪队列尾部
{
//printf("时间片完,但是程序未执行完 放到就绪队列尾部\n");
int n;
proc[RunPoint].p_state='R'; // 进程状态修改为就绪
proc[RunPoint].p_next=-;
proc[RunPoint].p_excutetime=-;//清空运行时间,-1代表程序未执行完成
if(ReadyPoint==-) // 就绪队列无进程
ReadyPoint=RunPoint;
else // 就绪队列有进程,放入队列尾
{
n=ReadyPoint;
while(proc[n].p_next!=-) n=proc[n].p_next;
proc[n].p_next=RunPoint;
}
RunPoint=-;
NextRunProcess(); //执行下一个进程
} } //////////////////////////////////////////////////////////////////////// // I/O调度 //////////////////////////////////////////////////////////////////////// void IO_Sched(void)
{
int n,bk; if (WaitPoint==-) return; // 没有等待I/O的进程,直接返回 proc[WaitPoint].p_iotime--; // 进行1个时钟的I/O时间 if (proc[WaitPoint].p_iotime > ) return; // 还没有完成本次I/O // 进程的I/O完成处理
if (proc[WaitPoint].p_rserial[]==proc[WaitPoint].p_pos) //进程全部任务执行完成
{
FinishedProc++;
proc[WaitPoint].p_endtime = ClockNumber;
proc[WaitPoint].p_state ='F'; if(proc[WaitPoint].p_next==-)
{ WaitPoint=-;return ;}
else //调度下一个进程进行I/O操作
{
n=proc[WaitPoint].p_next;
proc[WaitPoint].p_next=-;
WaitPoint=n;
proc[WaitPoint].p_iotime =proc[WaitPoint].p_rserial[proc[WaitPoint].p_pos] ;
return ;
}
}
else //进行下次CPU操作,进就绪队列
{
bk=WaitPoint;
WaitPoint=proc[WaitPoint].p_next; proc[bk].p_pos++;
proc[bk].p_state ='R'; //进程状态为就绪
proc[bk].p_cputime = proc[bk].p_rserial[proc[bk].p_pos];
proc[bk].p_next =-; n=ReadyPoint;
if(n == -) //是就绪队列的第一个进程
{ ReadyPoint=bk; return; }
else
{ do
{
if(proc[n].p_next == -) { proc[n].p_next = bk; break ; }
n=proc[n].p_next;
}
while(n!=-);
}
}
return ;
} //////////////////////////////////////////////////////////////////////// // 检查是否有新进程到达,有则放入就绪队列 //////////////////////////////////////////////////////////////////////// void NewReadyProc(void)
{
int i,n; for(i=; i<ProcNumber; i++)
{
if (proc[i].p_starttime == ClockNumber) // 进程进入时间达到系统时间
{
proc[i].p_state='R'; // 进程状态修改为就绪
proc[i].p_next=-; if(ReadyPoint==-) // 就绪队列无进程
ReadyPoint=i;
else // 就绪队列有进程,放入队列尾
{
n=ReadyPoint;
while(proc[n].p_next!=-) n=proc[n].p_next;
proc[n].p_next=i;
}
}
} // for
return;
} //////////////////////////////////////////////////////////////////////// // 调度模拟算法 //////////////////////////////////////////////////////////////////////// void Scheduler_FF(void)
{
FinishedProc=;
if(ProcNumber==)
{ printf(" 必须首先建立进程调度数据 ! \n");
system("cls"); return;
} ClockNumber=;// 时钟开始计时, 开始调度模拟
while(FinishedProc < ProcNumber) // 执行算法
{
ClockNumber++; // 时钟前进1个单位
NewReadyProc(); // 判别新进程是否到达
Cpu_Sched(); // CPU调度
IO_Sched(); // IO调度
Display_ProcInfo(); //显示当前状态
}
DisResult();
getch(); return;
} void Change_q(void)
{
scanf("%d",&q);
} /////////////////////////////////////////////////////////////////// // 主函数 /////////////////////////////////////////////////////////////////// int main(int argc, char* argv[])
{
char ch; RunPoint=-; // 运行进程指针,-1时为没有运行进程
WaitPoint=-; // 阻塞队列指针,-1时为没有阻塞进程
ReadyPoint=-; // 就绪队列指针,-1时为没有就绪进程
ClockNumber=; // 系统时钟
ProcNumber=; // 当前系统中的进程总数 system("cls") ;
while ( true )
{
printf("***********************************\n");
printf(" 1: 建立进程调度数据序列 \n") ;
printf(" 2: 执行调度算法\n") ;
printf(" 3: 显示调度结果 \n") ;
printf(" 4: 更改时间片 \n");
printf(" 5: 退出\n") ;
printf("***********************************\n");
printf( "Enter your choice (1 ~ 5): "); do{ //如果输入信息不正确,继续输入
ch = (char)_getch() ;
} while(ch != '' && ch != ''&& ch != ''&& ch != ''&& ch != ''); if(ch == '') { printf( "\n");return ; } // 选择4,退出
if(ch == '') DisResult(); // 选择3
if(ch == '') Scheduler_FF(); // 选择2
if(ch == '') Create_ProcInfo(); // 选择1
if(ch == '') Change_q();
_getch() ;
system("cls") ;
}
//结束
printf("\nPress Any Key To Continue:");
_getch() ;
return ;
}

操作系统,时间片轮转算法的C语言实现Round Robin的更多相关文章

  1. 魔方阵算法及C语言实现

    1 魔方阵概念 填充的,每一行.每一列.对角线之和均相等的方阵,阶数n = 3,4,5….魔方阵也称为幻方阵. 例如三阶魔方阵为: 魔方阵有什么的规律呢? 魔方阵分为奇幻方和偶幻方.而偶幻方又分为是4 ...

  2. 一个UUID生成算法的C语言实现 --- WIN32版本 .

    一个UUID生成算法的C语言实现——WIN32版本   cheungmine 2007-9-16   根据定义,UUID(Universally Unique IDentifier,也称GUID)在时 ...

  3. 无限大整数相加算法的C语言源代码

    忙里偷闲,终于完成了无限大整数相加算法的C语言代码,无限大整数相加算法的算法分析在这里. 500位的加法运行1000次,不打印结果的情况下耗时0.036秒,打印结果的情况下耗时16.285秒. 下面是 ...

  4. 数据结构算法集---C++语言实现

    //数据结构算法集---C++语言实现 //各种类都使用模版设计,可以对各种数据类型操作(整形,字符,浮点) /////////////////////////// // // // 堆栈数据结构 s ...

  5. 1164: 零起点学算法71——C语言合法标识符(存在问题)

    1164: 零起点学算法71——C语言合法标识符 Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: 10 ...

  6. 【最全】经典排序算法(C语言)

    算法复杂度比较: 算法分类 一.直接插入排序 一个插入排序是另一种简单排序,它的思路是:每次从未排好的序列中选出第一个元素插入到已排好的序列中. 它的算法步骤可以大致归纳如下: 从未排好的序列中拿出首 ...

  7. PID算法(c 语言)(转)

    PID算法(c 语言)(来自老外) #include <stdio.h> #include<math.h> //定义PID 的结构体 struct _pid { int pv; ...

  8. 一个UUID生成算法的C语言实现——WIN32版本

    源: 一个UUID生成算法的C语言实现——WIN32版本

  9. 排序算法总结(C语言版)

    排序算法总结(C语言版) 1.    插入排序 1.1     直接插入排序 1.2     Shell排序 2.    交换排序 2.1     冒泡排序 2.2     快速排序 3.    选择 ...

随机推荐

  1. JAVA基础第四章-集合框架Collection篇

    业内经常说的一句话是不要重复造轮子,但是有时候,只有自己造一个轮子了,才会深刻明白什么样的轮子适合山路,什么样的轮子适合平地! 我将会持续更新java基础知识,欢迎关注. 往期章节: JAVA基础第一 ...

  2. Java注解(二):实战 - 直接使用对象列表生成报表

    通过对Java注解(一):介绍,思想及优点学习了解,相信大家对Java注解有一定程度的了解,本篇文章将实战项目中的应用来加深对Java注解的了解. 本实例实现根据指定字段的JavaBean,生成对应列 ...

  3. AI繁荣下的隐忧——Google Tensorflow安全风险剖析

    本文由云+社区发表 作者:[ Tencent Blade Team ] Cradmin 我们身处一个巨变的时代,各种新技术层出不穷,人工智能作为一个诞生于上世纪50年代的概念,近两年出现井喷式发展,得 ...

  4. 【spring实战第五版遇到的坑】第14章spring.cloud.config.uri和token配置项无效

    本文使用的Spring Boot版本为:2.1.4.RELEASE Spring Cloud版本为:Greenwich.SR1 按照书上的做法,在application.yml中配置配置服务器的地址和 ...

  5. 设计模式之迭代器模式——Java语言描述

    迭代器模式是Java和.NET编程环境中非常常用的设计模式.这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示 介绍 意图 提供一种方法顺序访问一个聚合对象中各个元素,无需暴露该对象的内 ...

  6. vue3+typescript引入外部文件

    vue3+typescript中引入外部文件有几种方法 (eg:引入echarts) 第一种方法: 1 indext.html中用script引入 <div id="app" ...

  7. GitLab11.3.9 使用 Crowd3.3.2 的帐号实现 SSO 单点登录,以及GitLab配置腾讯企业邮箱

    GitLab11.3.9 的安装方法: 点击查看.   Crowd3.3.2 的安装方法:点击查看.   需要先在 Crowd 创建应用程序,参考 <Docker 创建 Crowd3.3.2 以 ...

  8. linux常用命令小结

    其他类 clear 清屏 文件管理 chmod 修改文件权限. 常用列表: chmod +x 使文件变为可执行文件. 常用于sh脚本. touch 创建文件 tar 压缩文件操作. -zxvf, 解压 ...

  9. How to fix corrupt HDFS FIles

    1 问题描述 HDFS在机器断电或意外崩溃的情况下,有可能出现正在写的数据(例如保存在DataNode内存的数据等)丢失的问题.再次重启HDFS后,发现hdfs无法启动,查看日志后发现,一直处于安全模 ...

  10. Unsupported major.minor version 52.0解决办法

    一.错误现象:当改变了jdk版本时,在编译java时,会遇到Unsupported major.minor version错误.jdk版本和stanford parser对应关系 JDK版本和Java ...