操作系统,时间片轮转算法的C语言实现Round Robin
#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的更多相关文章
- 魔方阵算法及C语言实现
1 魔方阵概念 填充的,每一行.每一列.对角线之和均相等的方阵,阶数n = 3,4,5….魔方阵也称为幻方阵. 例如三阶魔方阵为: 魔方阵有什么的规律呢? 魔方阵分为奇幻方和偶幻方.而偶幻方又分为是4 ...
- 一个UUID生成算法的C语言实现 --- WIN32版本 .
一个UUID生成算法的C语言实现——WIN32版本 cheungmine 2007-9-16 根据定义,UUID(Universally Unique IDentifier,也称GUID)在时 ...
- 无限大整数相加算法的C语言源代码
忙里偷闲,终于完成了无限大整数相加算法的C语言代码,无限大整数相加算法的算法分析在这里. 500位的加法运行1000次,不打印结果的情况下耗时0.036秒,打印结果的情况下耗时16.285秒. 下面是 ...
- 数据结构算法集---C++语言实现
//数据结构算法集---C++语言实现 //各种类都使用模版设计,可以对各种数据类型操作(整形,字符,浮点) /////////////////////////// // // // 堆栈数据结构 s ...
- 1164: 零起点学算法71——C语言合法标识符(存在问题)
1164: 零起点学算法71——C语言合法标识符 Time Limit: 1 Sec Memory Limit: 64 MB 64bit IO Format: %lldSubmitted: 10 ...
- 【最全】经典排序算法(C语言)
算法复杂度比较: 算法分类 一.直接插入排序 一个插入排序是另一种简单排序,它的思路是:每次从未排好的序列中选出第一个元素插入到已排好的序列中. 它的算法步骤可以大致归纳如下: 从未排好的序列中拿出首 ...
- PID算法(c 语言)(转)
PID算法(c 语言)(来自老外) #include <stdio.h> #include<math.h> //定义PID 的结构体 struct _pid { int pv; ...
- 一个UUID生成算法的C语言实现——WIN32版本
源: 一个UUID生成算法的C语言实现——WIN32版本
- 排序算法总结(C语言版)
排序算法总结(C语言版) 1. 插入排序 1.1 直接插入排序 1.2 Shell排序 2. 交换排序 2.1 冒泡排序 2.2 快速排序 3. 选择 ...
随机推荐
- [AST实战]从零开始写一个wepy转VUE的工具
为什么需要 wepy 转 VUE "转转二手"是我司用 wepy 开发的功能与 APP 相似度非常高的小程序,实现了大量的功能性页面,而新业务 H5 项目在开发过程中有时也经常需要 ...
- java游戏开发杂谈 - 画布和画笔
在Eclipse里,编写如下两个类: package game2; import java.awt.Color; import java.awt.Graphics; import javax.swin ...
- Asp.net Core 2.1新功能Generic Host(通用主机),了解一下
什么是Generic Host ? 这是在Asp.Net Core 2.1加入了一种新的Host,现在2.1版本的Asp.Net Core中,有了两种可用的Host. Web Host –适用于托管W ...
- 用C语言做一个横板过关类型的控制台游戏
前言:本教程是写给刚学会C语言基本语法不久的新生们. 因为在学习C语言途中,往往只能写控制台代码,而还能没接触到图形,也就基本碰不到游戏开发. 所以本教程希望可以给仍在学习C语言的新生们能提前感受到游 ...
- 关于.net导出数据到excel/word【占位符替换】
1]excel的占位符替换 效果如图 关键代码: ///savedFilePath需要保存的路径 templateDocPath模板路径 替换的关键字和值 格式 [姓名]$%$小王 public st ...
- 在编写Arcgis Engine 过程中对于接口引用和实现过程过产生的感悟
Engine10.2版本 在vs里面新建类GeoMaoAO,并定义接口,在class中定义并实现,如下代码 以平时练习为例,我定义了一个接口,在里面定义了许多的控件,并在类中想要实现这一接口.如果在v ...
- Python中使用type、metaclass动态创建方法和属性
1: type() 我们知道动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的. 比方说我们要定义一个Person的class: class Person(obj ...
- 24, CSS 构造超链接
1. 超链接边框 2. 派生超链接 3. 属性选择器超链接 4. 动态超链接 5. 图像翻转超链接 6. CSS 工具提示 1.给链接加上边框 A:link { Color: #f00; Text-d ...
- 涨姿势:抛弃字母、数字和下划线写SHELL
PHP中异或 (^) 的概念 <?php echo"A"^"?";?> <?php echo"A"^"?&quo ...
- 【转载】 Sqlserver中查看自定义函数被哪些对象引用
Sqlserver数据库中支持自定义函数,包含表值函数和标量值函数,表值函数一般返回多个数据行即数据集,而标量值函数一般返回一个值,在数据库的存储过程中可调用自定义函数,也可在该自定义函数中调用另一个 ...