操作系统实验指导4.docx
《操作系统实验指导4.docx》由会员分享,可在线阅读,更多相关《操作系统实验指导4.docx(17页珍藏版)》请在冰豆网上搜索。
操作系统实验指导4
实验四带优先级的时间片轮换的进程调度算法的实现
实验学时:
2
实验类型:
设计
实验要求:
必修
一、实验目的
(1)掌握进程状态转换过程
(2)掌握时间片轮转的进程调度算法;
(3)掌握带优先级的进程调度算法;
二、实验内容
(1)自定义PCB的数据结构;
(2)使用带优先级的时间片轮转法调度进程,每运行一个时间片,优先级减1。
(3)命令集
A)create随机创建进程,进程的优先级与所需要的时间片随机决定;
B)round执行1次时间片轮转操作,其方法为运行高优先级队列的第1个,再降低其优先级,插入到相应的队列中。
C)ps查看当前进程状态
D)sleep命令将进程阻塞
E)awake命令唤醒1个被阻塞的进程
F)kill命令删除进程
G)quit命令退出
(4)选用面向对象的编程方法。
三、实验原理或算法
本实验结合了进程状态转换、优先级调度、时间片轮转调度三方面的内容,根据进程状态转换图,设置SLEEP命令,将1个进程阻塞,AWAKE命令唤醒1个被阻塞的进程(从阻塞状态到就绪状态)。
1)优先级
优先级体现了进程的重要程度或紧迫程度,在大多数现代操作系统中,都采用了优先级调度策略。
在本实验中按数值大小决定优先级,数值大的优先级高(如0-2)。
2)基于时间片调度
将所有的就绪进程按照先来先服务的原则,排成一个队列,每次调度时,将cpu分配给队首进程,并令其执行一个时间片。
当时间片用完时,由一个计时器发出时钟中断请求,调度程序把此进程终止,并放到其他队列的队尾。
在该实验中,时间片以QUANTUM=2为单位进行模拟。
在调度过程中,需要循环模拟进程的执行时间,当该进程执行时间≥时间片大小时,进行调度。
3)高优先级调度
优先级高的进程优先得到cpu,等该进程执行完毕后,另外的进程才能执行。
4)基于时间片的高优先级调度
在调度算法中,只有处于就绪状态的进程才能被调度,调度算法结合了优先级调度和时间片轮转调度算法,约定:
从最高优先级队列取第1个就绪状态的进程进行调度,时间片到后降低其优先级(减半),然后插入到低优先级队列的尾部,每次调度后,显示进程的状态。
四、程序清单
#include
#include
#include
//#include
#include
//定义进程数
#defineLEN10
//定义最高优先级
#defineMAXPIOR3
//定义时间片
#defineQUANTUM2
#definePCBsizeof(structpcb)
structpcb//PCB
{intident;//标识符
intstate;//状态0-就绪,1-运行,2-堵塞
intpior;//优先级,MAXPIOR为最高优先级*/
intlife;//生命期*/
structpcb*next;/*指针*/
}*array[MAXPIOR];//定义优先级队列
staticintidlist[LEN];/*标识符表,标识进程是否被创建,0为未创建*/
intlife=0;/*总生命期初始化为0*/
charstr[20];
charcommand[7][10];
voidinit();
intcreate();
voidkill(intx);
voidprocess();
voidround();
voidps();
//初始化命令
voidinit()
{
inti=0;
for(i=0;iarray[i]=NULL;
sprintf(command[0],"quit");
sprintf(command[1],"ps");
sprintf(command[2],"create");
sprintf(command[3],"kill");
sprintf(command[4],"round");
sprintf(command[5],"sleep");
sprintf(command[6],"awake");
}
//创建进程
intcreate()
{
inti=0,pior=0;
structpcb*p,*q,*s;
while(idlist[i]!
=0&&i<=LEN-1)
i++;
if(i==LEN)return-1;
idlist[i]=1;
srand((unsigned)time(NULL));//时间随机函数
pior=rand()%MAXPIOR;//随机产生优先级,设定为0-2的整数
//printf("pior=%d\n",pior);
s=(structpcb*)malloc(PCB);//createanodetokeeptheprocessmessege
s->ident=i;
s->state=0;
s->pior=pior;
s->life=1+rand()%20;//进程有生命期假设为1-20
s->next=NULL;
life=life+(s->life);
p=array[pior];//建立同优先级队列(链表)
if(p==NULL)
array[pior]=s;
else
{
while(p!
=NULL)
{
q=p;
p=p->next;
}
q->next=s;
}
printf("successcreateprocessid=%d,currentprocessstatedispbelow:
\n",s->ident);
ps();
//printf("enddisplay\n");
return1;
}
//显示每个优先级队列中的所有进程信息
voidps()
{inti=0;
structpcb*p;
for(i=0;i{p=array[i];
while(p!
=NULL)
{printf("id:
%d,state:
%d,pior:
%d,life:
%d\n",p->ident,p->state,p->pior,p->life);
p=p->next;
}
}
}
//阻塞进程
voidsleep(intx)
{
//寻找X所在指针,提示:
参考kill(intx)函数
//如果找不到,输出错误信息,如果找到,修改p->state的状态
//显示每个优先级队列中的所有进程信息
inti=0,test=0;
structpcb*p=NULL,*q=NULL;
while(test==0&&i!
=MAXPIOR)//
{p=array[i];
if(i!
=MAXPIOR&&p==NULL)
{
i++;continue;
}
while(p!
=NULL)
{
if(p->ident==x)
{
test=1;break;
}
else
{
q=p;p=p->next;
}
}
if(test==0)i++;
}/*寻找X所在指针*/
if(i==MAXPIOR){
printf("Invaildprocessnumber");
}
else
if(p->state==2)
printf("theprocess%dhasblocked,cannotsleepagain",p->ident);
else
p->state==2;
ps();
}
voidawake(intx)
{//代码同sleep(intx)函数
//寻找X所在指针,提示:
参考kill(intx)函数
//如果找不到,输出错误信息,如果找到,修改p->state的状态
//显示每个优先级队列中的所有进程信息
inti=0,test=0;
structpcb*p=NULL,*q=NULL;
while(test==0&&i!
=MAXPIOR)//
{p=array[i];
if(i!
=MAXPIOR&&p==NULL)
{
i++;continue;
}
while(p!
=NULL)
{
if(p->ident==x)
{
test=1;break;
}
else
{
q=p;p=p->next;
}
}
if(test==0)i++;
}/*寻找X所在指针*/
if(i==MAXPIOR){
printf("Invaildprocessnumber");
}
else
if(p->state==0)
printf("theprocess%dhasblocked,cannotawakeagain",p->ident);
else
p->state==0;
ps();
}
voidkill(intx)
{inti=0,test=0;
structpcb*p=NULL,*q=NULL;
while(test==0&&i!
=MAXPIOR)//
{p=array[i];
if(i!
=MAXPIOR&&p==NULL)
{
i++;continue;
}
while(p!
=NULL)
{
if(p->ident==x)
{
test=1;break;
}
else
{
q=p;p=p->next;
}
}
if(test==0)i++;
}/*寻找X所在指针*/
if(i==MAXPIOR)//找不到X所在指针
printf("Invaildprocessnumber.");
else//找到X所在指针,则将其从优先级队列中删除
{
if(p==array[i])
{
array[i]=array[i]->next;
idlist[x]=0;
free(p);
}
else
{
q->next=p->next;
idlist[x]=0;
life=life-(p->life);
free(p);
}
}
}
//对输入命令的处理
voidprocess()
{inti=0,ii=0;
for(i=0;i<7;i++)
if(stricmp(str,command[i])==0)
break;
switch(i)
{case0:
printf("thankyouforusingtheprogram!
\n");exit(0);
break;
case1:
ps();
break;
case2:
create();
break;
case3:
{
printf("Whichprocessyouwanttokill?
\n");
scanf("%d",&ii);
kill(ii);
break;
}
case4:
round();break;
case5:
printf("Whichprocessyouwanttosleep?
\n");
scanf("%d",&ii);
sleep(ii);break;
case6:
printf("Whichprocessyouwanttoawake?
\n");
scanf("%d",&ii);
awake(ii);break;
default:
printf("Errorcommand.Pleaseinputcreate,ps,kill,sleep,awake,quit\n");
}
}
//模拟基于优先级的时间片轮转调度算法,
//执行一次调度运行,将最高优先级队列的进程运行1个时间片,并降低其优先级
voidround()
{
inti=MAXPIOR-1,pior=0,t;
structpcb*pp,*qq,*pr,*r;
do{
while(i>=0&&array[i]==NULL)
i=i--;
if(i<0)
{
printf("noprocess,pleasecreate!
");
return;
}
pr=r=array[i];
while(r!
=NULL&&r->state!
=0)
{
pr=r;
r=r->next;
}
i--;
}
while(r==NULL);
printf("theoneinthehighestpirorprocesswillexecute1quantum.");
r->state=1;
printf("processid=%disrunning",r->ident);
//从高优先队列开始,队列中寻找一个就绪进程以调度它,让其执行一个时间片
//执行过程:
//首先让进程处于运行状态,并给出“第x个进程正在运行”的提示信息
//其次,用下面用循环模拟延时,自己也可以采用其他方法
for(intk=1;k<600000;k++)
for(intk1=1;k1<1000;k1++);
printf("endchangetoready");
r->pior=(r->pior)/2;
r->state=0;
if(r->life-QUANTUM>0)
{
r->life=r->life-QUANTUM;
life=life-QUANTUM;
}
else
{
life=life-r->life;
r->life=0;
}
if(r->life==0)
{
printf("theprocess%dhassuccessrunandreleaseit",r->ident);
kill(r->ident);
}
else
{
if(pr==r)
array[i+1]=r->next;
else
pr->next=r->next;
t=r->pior;
pp=array[t];
qq=NULL;
while(pp!
=NULL)
{
qq=pp;
pp=pp->next;
}
if(qq==NULL)
array[t]=r;
else
qq->next=r;
r->next!
=NULL;
}
printf("after..");
ps();
printf("\n1quantumseccessfulrun!
\n");
//运行结束,并给出“第x个进程运行结束”的提示信息
//将进程优先级减半
//让进程处于就绪状态
//将进程的生命期减少,此时需要判断,如果该进程当前生命期>QUANTUM,
//则直接减去一个时间周期QUANTUM,否则,直接将进程当前生命期减为0
//进程的生命期为0,说明进程运行完成,KILL它,
//否则,将该进程结点从原队列中删除,并将其加入到相应低优先级队列中的最后
//调用ps()输出运行一个周期后,所有优先级队列中的所有进程信息
//输出信息,提示一个周期成功运行
}
//**********************************
intmain()
{init();
printf("WelcometotheProcessSchedulingsystem.ThisprogramsimulatetheRound-RobinwithpirorSchedulingalogrithm.\n");
printf("c:
\\>");
scanf("%s",str);
process();
while(strcmp(str,"quit")!
=0)
{
printf("\nc:
\\>");
scanf("%s",str);
process();
}
}五、实习报告要求:
1.代码补充:
请利用提供的代码框架补充代码,完成sleep,awake和round函数。
补充代码如上!
2.思考题:
读懂程序并画出您所用的数据结构简图;至少包含:
连续创建进程0~5的过程中,得到的按优先级存放的结构;
3.对不同的执行结果进行截图,并对截图进行说明,截图至少要包含创建后的初始状态,阻塞部分进程后的状态,再唤醒部分进程后的状态,删除部分进程后的状态,运行1个时间周期、3个时间周期和个5时间周期的各优先级队列的进程状态截图;
4.给出round和sleep,awake函数的代码,本次实习不用单独交代码。
补充代码如上!
六.实验总结
本次代码结合老师给的示例以及和同学交流之后完成,通过这次实验我学到了很多。
对于时间片轮转有了更深的认识!