实验五模拟进度调度.docx
《实验五模拟进度调度.docx》由会员分享,可在线阅读,更多相关《实验五模拟进度调度.docx(29页珍藏版)》请在冰豆网上搜索。
![实验五模拟进度调度.docx](https://file1.bdocx.com/fileroot1/2023-4/25/107af370-36b4-4bf8-8056-eeb7dda455c7/107af370-36b4-4bf8-8056-eeb7dda455c71.gif)
实验五模拟进度调度
实验五模拟进度调度
班级:
09网络工程姓名:
林泽全学号:
091402116
1、实验目的
1.理解PCB
2.理解进程的并发执行
3.理解进程的FCFS、动态优先权和时间片轮转三种调度算法,并模拟实现这三种算法
2、实验器材
微型计算机、fedora版本的Linux系统
3、实验内容
PCB在本设计中的基本结构
Typedefstructnode
{
Charname[10];/*进程标识符*/
Floatprin;/*进程的优先级*/
Intround;/*进程轮转的时间片*/
Intneedtime;/*进程还需要的cpu时间*/
Intwaittime;/*进程进入系统后等待cpu的时间*/
Charstate;/*进程的状态*/
Structnode*next;/*链接指针*/
}PCB
设计三个队列:
就绪、完成、运行,其中运行队列中应该只有一个进程。
创建进程,就是用户输入进程的标识符和运行所需时间,系统为其生成一个PCB,存放进程的信息,将新生成的PCB插入就绪队列。
进程任务结束,系统将其PCB插入完成队列,该进程就消亡。
任务1:
动态优先权调度算法模拟:
优先权=1+等待时间/需要服务时间----最高响应比优先
(1)输入一批作业的进程标识和估计运行时间,将其PCB插入就绪队列
(2)当就绪队列非空、CPU空闲时,计算出每个就绪进程的优先权
(3)将优先权最高的进程从就绪队列移入运行队列,状态改为运行(模拟进程调度)
(4)在屏幕上输出当前所有进程的状态和优先权信息(已完成进程不显示)
(5)让运行进程执行足够的服务时间
(6)将运行进程移入完成队列
(7)提示可以输入新的作业,如果有新作业输入,则转向
(1),否则转向
(2)
(8)如果就绪队列为空,则结束
程序框图如下:
程序源代码如下:
#include
#include
typedefstructnode
{
charname[10];//进程标识符
floatprin;//进程的优先级
intround;//进程轮转的时间片
intneedtime;//进程还需要当CPU时间
intwaittime;//进程进入系统后等待当CPU的时间
charstate;//进程当状态
structnode*next;//链接指针
}PCB;
PCB*readyQueue=NULL,*runningQueue=NULL,*finishedQueue=NULL,*finishedQueueTail=NULL,*readyQueueTail=NULL,pcbPool[10];
intpoolSize=0;
voidcreatePro();//根据进程标识和估计运行时间,将其PCB插入就绪队列
voidreadyQueueNotNull();//当就绪队列非空、CPU空闲时,计算每个就绪进程当优先权
voidinsertRunningQueue();//将优先权最高当进程从就绪队列移入运行队列,状态改为运行
voiddisplayQueue();//将所有非结束进程的状态和优先权信息显示在屏幕
voidrunPro();//让运行进程执行足够的服务时间
voidaddNewPro();//提示可以输入新的进程
intmain(intargc,charconst*argv[])
{
createPro();
while(readyQueue!
=NULL)
{
readyQueueNotNull();
insertRunningQueue();
displayQueue();
runPro();
puts("");
addNewPro();
}
puts("Bye");
return0;
}
voidcreatePro()
{
charname[10];
charstop='y';
intneedtime,i=0;
while(stop=='y')
{
//获取用户输入进程名
puts("Pleaseinputtheprocessname:
");
scanf("%s",name);
strcpy(pcbPool[i].name,name);
//获取用户输入进程需要时间
puts("Pleaseinputtheneedoftime:
");
scanf("%d",&needtime);
pcbPool[i].needtime=needtime;
pcbPool[i].state='0';
pcbPool[i].next=NULL;
pcbPool[i].prin=0.0f;
pcbPool[i].waittime=0;
if(i==0)
{
readyQueue=&pcbPool[0];
readyQueueTail=&pcbPool[0];
}else{
readyQueueTail->next=&pcbPool[i];
readyQueueTail=&pcbPool[i];
}
if(i++>9)
break;
puts("Doyouwanttoinputmoreprocess(yorn):
");
scanf("%s",&stop);
}
poolSize=i+1;
}
voidreadyQueueNotNull()
{
PCB*pcb=readyQueue;
while
(1)
{
pcb->prin=1+pcb->waittime/pcb->needtime;
if(pcb->next==NULL)
break;
else
pcb=pcb->next;
}
}
voidinsertRunningQueue()
{
PCB*currentPCB=readyQueue,*lastPCB=readyQueue,*lastOfChosePCB=readyQueue,*chosePCB=readyQueue;
while
(1)
{
//选择优先级最高的进程
if(currentPCB->prinprin)
{
lastOfChosePCB=lastPCB;
chosePCB=currentPCB;
}
//判断就绪队列是否判断结束
if(currentPCB->next!
=NULL)
{
lastPCB=currentPCB;
currentPCB=currentPCB->next;
}else{
break;
}
}
chosePCB->state='1';//将优先级最高的进程状态标识为运行时
runningQueue=chosePCB;//将优先级最高的进程从就绪队列移入运行队列
//将优先级最高的进程从就绪队列中移出
if(readyQueue==chosePCB)
readyQueue=readyQueue->next;
else
lastOfChosePCB->next=chosePCB->next;
}
voiddisplayQueue()
{
if(readyQueue!
=NULL)
{
PCBpcb=*readyQueue;
while
(1)
{
printf("Process:
%sState:
%dprin:
%f\n",pcb.name,pcb.state,pcb.prin);
if(pcb.next==NULL)
break;
else
pcb=*(pcb.next);
}
}
if(runningQueue!
=NULL)
printf("Process:
%sState:
%dprin:
%f\n",runningQueue->name,runningQueue->state,runningQueue->prin);
}
voidrunPro()
{
sleep(runningQueue->needtime);
if(readyQueue!
=NULL)
{
PCB*pcb=readyQueue;
while
(1)
{
pcb->waittime=pcb->waittime+runningQueue->needtime;
if(pcb->next==NULL)
break;
else
pcb=pcb->next;
}
}
//将运行了需要时间的进程移入完成队列
if(finishedQueue==NULL)
{
finishedQueue=runningQueue;
finishedQueueTail=runningQueue;
finishedQueueTail->next=NULL;
}else{
finishedQueueTail->next=runningQueue;
finishedQueueTail=runningQueue;
}
//清理运行时队列
runningQueue->state='0';
runningQueue=NULL;
}
voidaddNewPro()
{
charname[10];
charstop='y';
intneedtime,i=poolSize-1;
puts("Doyouwanttoinputmoreprocess(yorn):
");
scanf("%s",&stop);
while(stop=='y')
{
//获取用户输入进程名
puts("Pleaseinputtheprocessname:
");
scanf("%s",name);
strcpy(pcbPool[i].name,name);
//获取用户输入进程需要时间
puts("Pleaseinputtheneedoftime:
");
scanf("%d",&needtime);
pcbPool[i].needtime=needtime;
pcbPool[i].state='0';
pcbPool[i].next=NULL;
pcbPool[i].prin=0.0f;
pcbPool[i].waittime=0;
if(readyQueue==NULL)
{
readyQueue=&pcbPool[i];
readyQueueTail=&pcbPool[i];
}else{
readyQueueTail->next=&pcbPool[i];
readyQueueTail=&pcbPool[i];
}
if(i++>9)
break;
else
puts("Doyouwanttoinputmoreprocess(yorn):
");
scanf("%s",&stop);
}
poolSize=i+1;
}
程序运行截图如下:
任务2:
时间片轮转调度算法模拟
输入一批作业的进程标识和估计运行时间,由其PCB组成就绪队列。
时间片轮转调度,系统给就绪队列的第一个进程分配一个时间片,大小等于n(个时钟周期),再将它移入运行队列。
注意,时间片的大小要比大多数进程的估计运行时间短。
当时间片结束的时候,要将没有运行完的进程从运行队列移到就绪队列的末尾,再次进行调度。
在每次调度时将所有进程的当前情况显示出来。
程序框图如下:
程序源代码如下:
#include
#include
typedefstructnode
{
charname[10];//进程标识符
floatprin;//进程的优先级
intround;//进程轮转的时间片
intneedtime;//进程还需要当CPU时间
intwaittime;//进程进入系统后等待当CPU的时间
charstate;//进程当状态
structnode*next;//链接指针
}PCB;
PCB*readyQueue=NULL,*runningQueue=NULL,*finishedQueue=NULL,*finishedQueueTail=NULL,*readyQueueTail=NULL,pcbPool[10];
intpoolSize=0;
voidcreatePro();//根据进程标识和估计运行时间,将其PCB插入就绪队列
voidinsertRunningQueue();//将优先权最高当进程从就绪队列移入运行队列,状态改为运行
voiddisplayQueue();//将所有非结束进程的状态和优先权信息显示在屏幕
voidrunPro();//让运行进程执行足够的服务时间
intmain(intargc,charconst*argv[])
{
createPro();
while(readyQueue!
=NULL)
{
insertRunningQueue();
displayQueue();
runPro();
puts("");
}
puts("Bye");
return0;
}
voidcreatePro()
{
charname[10];
charstop='y';
intneedtime,i=0;
while(stop=='y')
{
//获取用户输入进程名
puts("Pleaseinputtheprocessname:
");
scanf("%s",name);
strcpy(pcbPool[i].name,name);
//获取用户输入进程需要时间
puts("Pleaseinputtheneedoftime:
");
scanf("%d",&needtime);
pcbPool[i].needtime=needtime;
pcbPool[i].state='0';
pcbPool[i].next=NULL;
pcbPool[i].prin=0.0f;
pcbPool[i].round=1;
if(i==0)
{
readyQueue=&pcbPool[0];
readyQueueTail=&pcbPool[0];
}else{
readyQueueTail->next=&pcbPool[i];
readyQueueTail=&pcbPool[i];
}
if(i++>9)
break;
puts("Doyouwanttoinputmoreprocess(yorn):
");
scanf("%s",&stop);
}
poolSize=i+1;
}
voidinsertRunningQueue()
{
runningQueue=readyQueue;
readyQueue=readyQueue->next;
runningQueue->state='1';
}
voiddisplayQueue()
{
if(readyQueue!
=NULL)
{
PCBpcb=*readyQueue;
while
(1)
{
printf("Process:
%sState:
%dNeedtime:
%d\n",pcb.name,pcb.state,pcb.needtime);
if(pcb.next==NULL)
break;
else
pcb=*(pcb.next);
}
}
if(runningQueue!
=NULL)
printf("Process:
%sState:
%dNeedtime:
%d\n",runningQueue->name,runningQueue->state,runningQueue->needtime);
}
voidrunPro()
{
sleep(runningQueue->round);//模拟执行进程
//更新运行队列
runningQueue->needtime=runningQueue->needtime-runningQueue->round;
runningQueue->state='0';
//将运行结束当进程移入完成队列
if(runningQueue->needtime<=0)
{
if(finishedQueue==NULL)
{
finishedQueue=runningQueue;
finishedQueueTail=runningQueue;
finishedQueueTail->next=NULL;
}else{
finishedQueueTail->next=runningQueue;
finishedQueueTail=runningQueue;
}
}else{
if(readyQueue==NULL)
{
readyQueue=runningQueue;
readyQueueTail=runningQueue;
}else{
readyQueueTail->next=runningQueue;
readyQueueTail=runningQueue;
}
}
readyQueueTail->next=NULL;
//清理运行时队列
runningQueue=NULL;
}
程序运行截图如下:
任务2:
FCFS调度算法模拟
按一定的顺序输入一批作业的进程标识和估计运行时间,由其PCB按照进程标识输入的顺序组成就绪队列。
当就绪队列非空、CPU空闲时,将就绪队列的第一个进程从就绪队列移入运行队列,状态改为运行。
以后个步骤类似于2。
程序框图如下:
程序源代码如下:
#include
#include
typedefstructnode
{
charname[10];//进程标识符
floatprin;//进程的优先级
intround;//进程轮转的时间片
intneedtime;//进程还需要当CPU时间
intwaittime;//进程进入系统后等待当CPU的时间
charstate;//进程当状态
structnode*next;//链接指针
}PCB;
PCB*readyQueue=NULL,*runningQueue=NULL,*finishedQueue=NULL,*finishedQueueTail=NULL,*readyQueueTail=NULL,pcbPool[10];
intpoolSize=0;
voidcreatePro();//根据进程标识和估计运行时间,将其PCB插入就绪队列
voidinsertRunningQueue();//将优先权最高当进程从就绪队列移入运行队列,状态改为运行
voiddisplayQueue();//将所有非结束进程的状态和优先权信息显示在屏幕
voidrunPro();//让运行进程执行足够的服务时间
voidaddNewPro();//提示可以输入新的进程
intmain(intargc,charconst*argv[])
{
createPro();
while(readyQueue!
=NULL)
{
insertRunningQueue();
displayQueue();
runPro();
puts("");
addNewPro();
}
puts("Bye");
return0;
}
voidcreatePro()
{
charname[10];
charstop='y';
intneedtime,i=0;
while(stop=='y')
{
//获取用户输入进程名
puts("Pleaseinputtheprocessname:
");
scanf("%s",name);
strcpy(pcbPool[i].name,name);
//获取用户输入进程需要时间
puts("Pleaseinputtheneedoftime:
");
scanf("%d",&needtime);
pcbPool[i].needtime=needtime;
pcbPool[i].state='0';
pcbPool[i].next=NULL;
pcbPool[i].prin=0.0f;
pcbPool[i].waittime=0;
if(i==0)
{
readyQueue=&pcbPool[0];
readyQueueTail=&pcbPool[0];
}else{
readyQueueTail->next=&pcbPool[i];
readyQueueTail=&pcbPool[i];
}
if(i++>9)
break;
puts("Doyouwanttoinputmoreprocess(yorn):
");
scanf("%s",&stop);
}