#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. numpy C语言源代码调试(三)

    鉴于ddd过于简陋,希望找一个新一些的调试工具,看到有很多人推荐gdbgui,这是一个非常新的调试工具,前端使用浏览器,现在采用这一架构的软件越来越多,可以完全不必依赖庞大的gui类库,安装使用比较方 ...

  2. 理解线程池到走进dubbo源码

    引言 合理利用线程池能够带来三个好处. ​ 第一:降低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗. ​ 第二:提高响应速度.当任务到达时,任务可以不需要等到线程创建就能立即执行. ...

  3. TensorFlow从1到2(七)线性回归模型预测汽车油耗以及训练过程优化

    线性回归模型 "回归"这个词,既是Regression算法的名称,也代表了不同的计算结果.当然结果也是由算法决定的. 不同于前面讲过的多个分类算法或者逻辑回归,线性回归模型的结果是 ...

  4. NumPy 超详细教程(3):ndarray 的内部机理及高级迭代

    系列文章地址 NumPy 最详细教程(1):NumPy 数组 NumPy 超详细教程(2):数据类型 NumPy 超详细教程(3):ndarray 的内部机理及高级迭代 ndarray 对象的内部机理 ...

  5. gitbook 入门教程之使用 gitbook-cli 开发电子书

    gitbook 生成电子书主要有三种方式: gitbook-cli 命令行操作,简洁高效,适合从事软件开发的相关人员. gitbook-editor 编辑器操作,可视化编辑,适合无编程经验的文学创作者 ...

  6. github SSH配置

    目录 github SSH配置 前言 ssh 配置 github SSH配置 前言 github有两种更新的渠道,一种是https的,一种是ssh的,其中https每次都要输入密码,非常烦.所以,最好 ...

  7. 【jframe】Java架构师之路 - 第01篇:Get Started

    jframe是什么? jframe是一个基于MIT协议开源的java web应用程序框架,汇聚了我们团队之于java web应用程序的核心架构思想以及大量最佳实践,并且持续在实际项目中不断完善优化. ...

  8. 解决微信公众号授权登录和开放平台微信第三方应用授权登录获取到的用户Openid关联问题

    开发背景: 最近一段时间一直在做关于微信方面的网站应用开发,这段时间也收获的不少关于微信开发方面的开发技能,接触的比较多的主要有微信公众号和微信网站app第三方登录授权,以及微信会员卡,优惠券和扫描二 ...

  9. markdown用法

    Markdown 语法的目标是成为一种适用于网络的书写语言.不在 Markdown 涵盖范围之内的标签,都可以直接在文档里面用 HTML 撰写.不需要额外标注,只要直接加标签就可以了. 一.常用部分 ...

  10. Yii2 解决2006 MySQL server has gone away问题

    Yii2 解决2006 MySQL server has gone away问题 Yii2版本 2.0.15.1 php后台任务经常包含多段sql,如果php脚本执行时间较长,或者sql执行时间较长, ...