操作系统,时间片轮转算法的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. 选择 ...
随机推荐
- 网页基础:网页设计(我所知道的所有的html和css代码(含H5和CSS3)),如有错误请批评指正
最基础的网页设计,就是给你一个图片你做成一个网页,当然,我的工作是C#,个人网页的功底不是很高首先先认识一下网页的一些相关知识: 一般的,现在一个html网页一般包含html文件,css文件,js文件 ...
- ASP.NET Core 项目实战(持续更新~~~)
一.前言 准备写这个系列文章的设想开始于今年9月,毫无意外,期间又又又又拖了很长时间,文章主要是为了记录自己学习使用 ASP.NET Core Web API 与 Vue 创建一个前后端分离的项目的整 ...
- Python爬虫入门教程 63-100 Python字体反爬之一,没办法,这个必须写,反爬第3篇
背景交代 在反爬圈子的一个大类,涉及的网站其实蛮多的,目前比较常被爬虫coder欺负的网站,猫眼影视,汽车之家,大众点评,58同城,天眼查......还是蛮多的,技术高手千千万,总有五花八门的反爬技术 ...
- 整合X-Admin前端框架改造ABP
“站在巨人的肩膀上”,这样一来,不要万事亲恭,在值得的方向上节约时间,毕竟人生就这么一次.在接触ABP以来,一直想花点时间整合LayUI前端框架到ABP中,进而能够逐渐打磨出一套适合自己的框架,开发习 ...
- Named Volume 在 MySQL 数据持久化上的基本应用
原文作者:春哥 初识春哥时,春哥是美术设计大咖.后不久,创业并致力于游戏开发,已有3年.从Unity3D到IOS(Swift)开发,从前端开发到后端以及容器技术,从设计开发测试到产品经理以及CEO,已 ...
- python之循序渐进学习装饰器
python装饰器的定义:在代码运行期间在不改变原函数定义的基础上,动态给该函数增加功能的方式称之为装饰器(Decorator) 装饰器的优点和用途: 1. 抽离出大量函数中与函数功能本身无关的的雷同 ...
- 使用JDBC操作MySQL数据库
一.JDBC简介 JDBC(Java DataBase Connectivity)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一的访问,它由一组用Java语言编写的类和接口组 ...
- PHP 单例模式优点意义及如何实现
一.什么是单例模式? 1.含义 作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个实例.它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用. 2. ...
- java.lang.UnsatisfiedLinkError:dlopen failed: “**/*/arm/*.so” has unexpected e_machine: 3
转载请标明出处,维权必究:https://www.cnblogs.com/tangZH/p/10458448.html 今天在做APP的时候使用so库,可结果一加载so库的时候便发生了这个莫名其妙的错 ...
- alter session set current_schema=Schema
使用CURRENT_SCHEMA之后,当前会话所参考的默认SCHEMA变为设置的用户,而不再是当前的用户:其实需要稍微理解一下user和schema的区别先:user即oracle中的用户,和所有系统 ...