#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. 如何优雅地在 Spring Boot 中使用自定义注解,AOP 切面统一打印出入参日志 | 修订版

    欢迎关注个人微信公众号: 小哈学Java, 文末分享阿里 P8 资深架构师吐血总结的 <Java 核心知识整理&面试.pdf>资源链接!! 个人网站: https://www.ex ...

  2. 页面性能优化-原生JS实现图片懒加载

    在项目开发中,我们往往会遇到一个页面需要加载很多图片的情况.我们可以一次性加载全部的图片,但是考虑到用户有可能只浏览部分图片.所以我们需要对图片加载进行优化,只加载浏览器窗口内的图片,当用户滚动时,再 ...

  3. Tensorflow源码解析1 -- 内核架构和源码结构

    1 主流深度学习框架对比 当今的软件开发基本都是分层化和模块化的,应用层开发会基于框架层.比如开发Linux Driver会基于Linux kernel,开发Android app会基于Android ...

  4. C语言sprintf和sscanf函数用法

    以前刚用C语言的时候,觉得字符串很难处理,后来用多了,发现其实并非如此,C语言也提供了许多函数给程序员使用.今天记录一下两个常用的两个字符串处理函数:sprintf和sscanf 1. sprintf ...

  5. 使用Http-Repl工具测试ASP.NET Core 2.2中的Web Api项目

    今天,Visual Studio中没有内置工具来测试WEB API.使用浏览器,只能测试http GET请求.您需要使用Postman,SoapUI,Fiddler或Swagger等第三方工具来执行W ...

  6. asp.net core系列 59 Ocelot 构建基础项目示例

    一.入门概述 从这篇开始探讨Ocelot,Ocelot是一个.NET API网关,仅适用于.NET Core,用于.NET面向微服务/服务的架构中.当客户端(web站点.ios. app 等)访问we ...

  7. 「Continuous_integration, CI」为什么要持续集成?

    前言   什么是持续集成,为什么要持续集成?本文对持续集成前后两种开发实践做了对比分析,从而直观的感受到持续集成的好处. 在说持续集成之前,先说一下传统的开发模式: 传统模式: 传统模式过程如下: 传 ...

  8. Linux三剑客-grep || awk || sed

    grep是一个强大的文本搜索工具 命令格式: grep [option] pattren file -a  将二进制文档以文本方式处理 -c  计算找到的符合行的次数 -i  忽略大小写 -n  顺便 ...

  9. ACM入门之OJ~

    所谓OJ,顾名思义Online Judge,一个用户提交的程序在Online Judge系统下执行时将受到比较严格的限制,包括运行时间限制,内存使用限制和安全限制等.用户程序执行的结果将被Online ...

  10. ArcGIS API for JavaScript 4.x 本地部署之Apache(含Apache官方下载方法)

    IIS.Nginx都说了,老牌的Apache和Tomcat也得说一说(如果喜欢用XAMPP另算) 本篇先说Apache. 安装Apache 这个...说实话,比Nginx难找,Apache最近的版本都 ...