静态优先权优先算法的进程调度程序文件.docx
《静态优先权优先算法的进程调度程序文件.docx》由会员分享,可在线阅读,更多相关《静态优先权优先算法的进程调度程序文件.docx(17页珍藏版)》请在冰豆网上搜索。
![静态优先权优先算法的进程调度程序文件.docx](https://file1.bdocx.com/fileroot1/2023-1/2/c6355860-8acf-4ab5-9d92-0a3a72a4245a/c6355860-8acf-4ab5-9d92-0a3a72a4245a1.gif)
静态优先权优先算法的进程调度程序文件
静态优先权优先算法的进程调度程序
学院
专业
学生姓名
学号
指导教师姓名
21014年3月19日
1.系统需求分析
1.1问题描述
1>设计并实现一个采用静态优先权算法的进程调度演示程序。
并且求出每个进程的周转时间以及带权周转时间。
2>静态优先权是在创建进程时确定的,且在进程的整个运行期间保持不变.
一般地,优先权是利用某一范围内的一个整数来表示的,例如,0~7或0~255中的某一整数,又把该整数称为优先数.只是具体用法各异:
有的系统用"0"表示最高优先权,当数值愈大时,其优先权愈低;而有的系统恰恰相反.
确定进程优先权的依据有如下三个方面:
a.进程类型.<系统进程/用户进程>
b.进程对资源的需求.<需求量的大小>
c.用户要求.<用户进程紧迫程度>
3>本程序采用优先级数字大的优先权大。
1.2功能要求
1每一个进程有一个PCB,其内容可以根据具体情况设定。
2进程数、进入内存时间、要求服务时间、优先级等均可以在界面上设定。
3可读取样例数据〔要求存放在外部文件中进行进程数、进入内存时间、进程优先级的初始化。
4可以在运行中显示各进程的状态:
就绪、执行〔由于不要求设置互斥资源与进程间的同步关系,故只有两种状态。
5具有一定的数据容错性。
2.总体设计
2.1总体设计图
系统总体设计如图2.1所示。
图2.1系统总体设计
2.2各模块功能
1>voidbuildProcess<>:
手动创建进程。
2>structPCB*callMemory<>:
将符合条件的进程调入内存。
3>voidListAllPCB:
打印所有进程到屏幕上。
4>voidMenu<>:
菜单以及执行。
5>voidnewPCB<>:
创建进程。
在1中被调用。
6>voidreadFromFile<>:
从文件中读取数据。
7>voidreadyList:
就绪列表。
8>voidrelease,voidreleaseR:
释放进程。
9>voidrun<>:
执行静态优先级进程调度算法。
10>structPCB*runTheProcess<>:
标识要执行的进程。
11>voidsetNewPCB:
创建进程。
在6中被调用。
12>inttimeOfData:
计算文件中进程数量。
在6中被调用。
2.3相关数据结构设计
结构体:
structPCB{}*head,*readyHead;
3.详细设计
3.1采用C语言定义的相关数据类型
structPCB
{
intArrivalTime;
intServiceTime;
charnumber[10];
};
structPCB*head,*thisP,*newP;//动态接收进程及详细
structPCB*readyHead;//动态存储就绪队列
采用结构体数组,创建一个进程,包含进程相关信息:
进程名称、进程优先级、进程到达时间、进程服务时间。
3.2调度算法的主要实现
structPCB*callMemory<>//调入内存,返回调入内存的链表节点。
将达到进程进入内存时间的所有进程调入内存。
voidreadyList//单链表的形式创建就绪队列。
将进入内存的进程调入就绪列表。
structPCB*runTheProcess<>//执行的进程,返回要执行进程的节点。
将就绪列表中满足运行条件的进程标识下来并返回节点。
voidrun<>//静态优先权算法。
将执行的程序释放。
调入新的满足执行条件的进程。
就绪列表释放。
4.运行结果
4.1系统调试
在程序设计初期。
本想采用冒泡排序将进入内存的进程进行优先级排序,不过最后总是排序失败。
最后想到我进行的是进程调度模拟,应该就有进程调入内存以及调入CPU,因此之后设计其他函数进行调入内存、CPU的模拟。
而且最后选择新建就绪列表,进行选择插入就绪列表中。
以及随时使用屏幕打印语句printf来测试程序各个阶段执行状态。
4.2功能实现界面
〔1主菜单:
如图4.1所示。
图4.1主菜单
〔2进程调度模拟。
图4.2创建进程
2>
图4.3进程运行过程
3>进程在调度算法中,计算出的具体的完成时间,周转时间,带权时间。
如图4.4所示。
图4.4进程运行结果
〔3选择2:
从文件读取数据。
如图4.5。
在f:
\test.txt中,数据如下。
//从文件读取数据
/*数据格式如下
进程名优先级到达时间服务时间
proc12110
proc22111
proc3322
*/
运行结果。
如图4.6
图4.6文件读取数据及运行结果
5.使用说明
根据屏幕提示输入即可。
需要用户注意的是优先级〔整数表示越大优先权越大。
6.心得体会
本次课程设计,第一天上午去拿课程设计题目采用静态优先权优先算法的进程调度程序,下午开始查找资料并且构思。
在网上看到一些课程设计用到的有数据结构体struct,便再度拿出C语言书本以及数据结构课本,主要看了数据结构体和单链表方面的知识。
上面也曾说到,程序设计初期打算在单链表中直接使用冒泡排序法进程优先级的排序,总是失败。
后来意识到,进程调度不仅要考虑到进程优先级,同时还有进入内存的时间。
因为只有到达进入内存的时间,进程才会被调入内存中,进一步通过满足条件被调入CPU中执行,或者说分配CPU进而执行。
所以索性模拟出调入内存方法以及调入CPU方法,与此有极大关系的是单链表就绪列表的建立。
进行代码编写以及测试,从而模拟进程调度算法完成。
7.附录
7.1源代码
#include
#include
#include
intSequenceNumber=1;//进程编号
intProcessAmount;//进程数量
intStartCount=0;//调入内存进程计数
structPCB{//进程控制块
intNo;//进程号
charname[16];//进程名
intenterMemoryTime;//进入内存时间
intserviceTime;//服务时间
intpriority;//优先级
structPCB*next;
};
structPCB*head,*thisP,*newP;//动态接收进程及详细
structPCB*readyHead;//动态存储就绪队列
//函数声明
intgetch<>;
inttimeOfData;
voidListAllPCB<>;
voidMenu<>;
voidprintPCB;
voidprintPCBP;
voidprintField<>;
voidprintFieldP<>;
voidrelease;
voidreleaseR;
voidsetNewPCB;
structPCB*runTheProcess<>;
voidnewPCB<>{//建立PCB
newP=malloc>;
if
{//判断头节点是否为空
head=newP;//为空,头节点指向新开辟的内存
}else{
thisP=head;
whilenext!
=NULL>{
thisP=thisP->next;
}
thisP->next=newP;//遍历单链表,找到最后一个元素
}
thisP=newP;
thisP->No=SequenceNumber;
SequenceNumber++;
printf<"进程号%d\n",thisP->No>;
printf<"输入进程名:
">;
scanf<"%s",thisP->name>;
printf<"输入优先级:
">;
scanf<"%d",&thisP->priority>;
printf<"输入进入内存时间:
">;
scanf<"%d",&thisP->enterMemoryTime>;
printf<"输入服务时间:
">;
scanf<"%d",&thisP->serviceTime>;
thisP->next=NULL;
}
voidbuildProcess<>{//创建进程
inti=0;
printf<"输入进程数量:
">;
scanf<"%d",&ProcessAmount>;
while{
newPCB<>;
i++;
}
}
voidreadyList{//单链表的形式创建就绪队列
newP=malloc>;
if{
readyHead=newP;
}else{
thisP=readyHead;
whilenext!
=NULL>{
thisP=thisP->next;
}
thisP->next=newP;
}
thisP=newP;
strcpyname,pcb->name>;
thisP->No=pcb->No;
thisP->priority=pcb->priority;
thisP->enterMemoryTime=pcb->enterMemoryTime;
thisP->serviceTime=pcb->serviceTime;
thisP->next=NULL;
}
structPCB*callMemory<>{//调入内存,返回调入内存的链表节点
intat;//到达时间
structPCB*markP;
if
{
printf<"程序没有找到。
\n">;
}else{
markP=thisP=head;//标记指向头节点
at=thisP->enterMemoryTime;//到达时间为头节点到达时间
whilenext!
=NULL>{//当下一节点不为空
ifthisP->next->enterMemoryTime>{//判断当前时间是否大于下一节点时间
markP=thisP->next;//是,标记此节点
at=markP->enterMemoryTime;//到达时间更改为标记时间
}
thisP=thisP->next;//向后遍历
}
}
returnmarkP;
}
voidrun<>{//静态优先级算法执行。
structPCB*temp;//临时节点用来存储调入内存节点
structPCB*runPro;//用来接收执行的节点
inti;//循环初始条件
intat,srt,runtime=0;//到达时间,开始执行时间,运行时间。
intturnOverTime;//周转时间
doubleptot;//带权周转时间
if
{
printf<"没有发现进程。
\n">;
}else{
for{//循环进程的数量次
while
=NULL>{
temp=callMemory<>;
if{//初始情况下球开始执行时间,完成时间,周转时间,带权周转时间
srt=at=temp->enterMemoryTime;
runtime=at+temp->serviceTime;
turnOverTime=runtime-at;
ptot=turnOverTime*1.0/temp->serviceTime;
}
readyList;//初始纳入就绪列表以及后续
release;//释放进程
while
=NULL&&>->enterMemoryTime<=runtime>{
readyList;//循环判断是否纳入就绪列表
release;
}
}
runPro=runTheProcess<>;
if0>{//初始之后,计算各时间及周转
srt=runtime;
runtime+=runPro->serviceTime;
turnOverTime=runtime-runPro->enterMemoryTime;
ptot=turnOverTime*1.0/runPro->serviceTime;
}
printf<"当前执行的进程:
\n">;
printField<>;
printPCB;
releaseR;
printf<"\n就绪进程列表:
\n">;
ListAllPCB;
printf<"\n">;
}
}
}
structPCB*runTheProcess<>{//执行的进程,返回要执行进程的节点
inttime,pri;
structPCB*markThis;//标记要返回的节点
if{
printf<"没有可运行的进程。
\n">;
}else{
markThis=thisP=readyHead;
time=thisP->enterMemoryTime;//当前到达时间
pri=thisP->priority;//当前进程的优先级
whilenext!
=NULL>{
if
ifnext->priority>{//一致,则判断优先级决定
pri=thisP->next->priority;//更改优先级判断条件为下一优先级
markThis=thisP->next;//标记当前节点的下一节点
}
}else{
break;
}
thisP=thisP->next;
}
}
returnmarkThis;
}
voidrelease{//删除原单链表的进程节点
structPCB*markP,*f;
markP=head;
if=NULL>{
if{
f=head;
head=head->next;
free;
}else{
thisP=head->next;
while=NULL>{
if{
f=thisP;
markP->next=thisP->next;
free;
break;
}else{
markP=thisP;
}
thisP=thisP->next;
}
}
}
}
voidreleaseR{//删除就绪列表中进程节点
structPCB*markP,*f;
markP=readyHead;
if=NULL>{
if{
f=readyHead;
readyHead=readyHead->next;
free;
}else{
thisP=readyHead->next;
while=NULL>{
if{
f=thisP;
markP->next=thisP->next;
free;
break;
}else{
markP=thisP;
}
thisP=thisP->next;
}
}
}
}
voidListAllPCB{//打印所有进程
printFieldP<>;
if{
printf<"没有进程。
\n">;
}else{
thisP=h;
while=NULL>{
printPCBP;
thisP=thisP->next;
}
}
printf<"\n按任意键继续...\n">;
getch<>;
printf<"\n\n">;
}
voidprintPCB{//打印单个数据结果
if=NULL>{
printf<"%-8s%-8d%-8d%-8d%-8d",pcb->name,pcb->No,pcb->priority,pcb->enterMemoryTime,pcb->serviceTime>;
printf<"%-8d%-8d%-8d%-8.2lf\n",a,b,c,d>;
}else
printf<"没有进程。
\n">;
}
voidprintPCBP{
if=NULL>
printf<"%-8s%-8d%-8d%-8d%-8d\n",pcb->name,pcb->No,pcb->priority,pcb->enterMemoryTime,pcb->serviceTime>;
else
printf<"没有进程。
\n">;
}
voidprintField<>{//打印表头,以及周转时间
printf<"\n">;
printf<"进程名\t进程号\t优先级\t到达时\t服务时\t开始执\t完成时\t周转时\t带权周\n">;
printf<"\t\t\t间\t间\t行时间\t间\t间\t转时间\n">;
}
voidprintFieldP<>{//打印表头,字段
printf<"\n">;
printf<"进程名\t进程号\t优先级\t到达时\t服务时\n">;
printf<"\t\t\t间\t间\n">;
}
//从文件读取数据
/*数据格式如下
进程名优先级到达时间服务时间
proc12110
proc22111
proc3322
*/
voidreadFromFile<>{
FILE*fp;
inttimes;
inti=0;
charfilePath[20],temp[8];
charname[16];
intpri,emt,st;
printf<"输入文件路径:
">;
scanf<"%s",filePath>;
fp=fopen;
times=timeOfData;
ProcessAmount=times-2;
while{
if{//这是用来接收文本格式第一行的汉字。
fscanf;
fscanf;
fscanf;
fscanf;
}else{//以下用来接收进程数据
fscanf;
fscanf;
fscanf;
fscanf;
setNewPCB;
}
i++;
}
fclose;
}
voidsetNewPCB{//赋值建立PCB,用于从文本中获取数据
newP=malloc>;
if
{
head=newP;
}else{
thisP=head;
whilenext!
=NULL>{
thisP=thisP->next;
}
thisP->next=newP;
}
thisP=newP;
thisP->No=SequenceNumber;
SequenceNumber++;
strcpyname,name>;
thisP->priority=pri;
thisP->enterMemoryTime=entime;
thisP->serviceTime=sertime;
thisP->next=NULL;
}
inttimeOfData{//求取从文本中获取数据的进程数量
chartemp[20];
inti=0;
if{
printf<"文件没有找到。
\n">;
exit<0>;
}else{
while!
=NULL>{
i++;
}
}
rewind;
returni;
}
voidMenu<>{//菜单
intflag=1;
intse;