CPU调度算法.docx
《CPU调度算法.docx》由会员分享,可在线阅读,更多相关《CPU调度算法.docx(17页珍藏版)》请在冰豆网上搜索。
CPU调度算法
一、设计目的
通过CPU调度相关算法的实现,了解CPU调度的相关知识,通过实现CPU调度算法,理解CPU的管理,以及不同的CPU调度算法实现过程。
体会算法的重要性。
二、设计要求
1、编写算法,实现FCFS、非抢占SJF、可抢占优先权调度
2、针对模拟进程,利用CPU调度算法进行调度
3、进行算法评估,计算平均周转时间和平均等待时间
4、调度所需的进程参数由输入产生(手工输入或者随机数产生)
5、输出调度结果
6、输出算法评价指标
三、设计说明
1、采用数组、指针
2、FCFS
先来先服务调度算法是一种最简单的调度算法,当作业调度中采用该算法时,每次调度都是从后备作业队列中选择一个最先进入该队列的作业
3、非抢占SJF
短作业优先调度算法,是指对短作业有限调度算法。
是从后备队列中选择一个估计运行时间最短的作业将他们调入存。
4、可抢占优先权调度
在这种方式下,系统把处理机分配给优先权最高的进程,使之执行。
但在其执行期间,只要出现另一个其优先权更高的进程,进程调度程序就立即停止当前进程(原优先权最高的进程)的执行,重新将处理及分配给新到的优先权最高的进程。
四、程序流程图。
1、可抢占优先权调度算法
2、FCFS3、非抢占SJF
五、程序部分
1、FCFS
#include
#include
typedefstructPCB
{
charname[10];
charstate;
intarrivetime;
intstarttime;
intfinishtime;
intservicetime;
floatturnaroundtime;
floatweightedturnaroundtime;
structPCB*next;
}pcb;
inttime;
intn;
pcb*head=NULL,*p,*q;
voidrun_fcfs(pcb*p1)
{time=p1->arrivetime>time?
p1->arrivetime:
time;p1->starttime=time;
printf("\n现在时间是%d,开始运行作业%s\n",time,p1->name);
time+=p1->servicetime;
p1->state="T";
p1->finishtime=time;
p1->turnaroundtime=p1->finishtime-p1->arrivetime;
p1->weightedturnaroundtime=p1->turnaroundtime/p1->servicetime;
printf("到达时间开始时间服务时间完成时间周转时间带权周转时间\n");
printf("%6d%10d%10d%8d%10.1f%10.2f\n",
p1->arrivetime,p1->starttime,p1->servicetime,p1->finishtime,p1->turnaroundtime,p1->weightedturnaroundtime);
}
voidfcfs()
{inti,j;
p=head;
for(i=0;i{if(p->state=='F')
{q=p;
run_fcfs(q);
}
p=p->next;}
}
voidgetInfo()
{intnum;
printf("\n作业个数:
");
scanf("%d",&n);
for(num=0;num{p=(pcb*)malloc(sizeof(pcb));
printf("依次输入:
进程名到达时间服务时间\n");
scanf("%s%d%d",&p->name,&p->arrivetime,&p->servicetime);
if(head==NULL)
{head=p;q=p;time=p->arrivetime;}
if(p->arrivetime
q->next=p;
p->starttime=0;
p->finishtime=0;
p->turnaroundtime=0;
p->weightedturnaroundtime=0;
p->next=NULL;
p->state='F';
q=p;}
}
voidmain()
{system("graftabl936");
printf("先来先服务算法模拟");
getInfo();
p=head;
fcfs();
getch();
}
2、非抢占SJF
#include
#include
#defineMAX100
structjcb{
charname[10];
floatarrivetime;
floatstarttime;
floatfinishtime;
floatservicetime;
floatzztime;
floatavezztime;
};
structjcba[MAX];
voidinput(jcb*p,intN)
{inti;
printf("请分别输入\n\t进程名到达时间服务时间\n\n");
for(i=0;i<=N-1;i++)
{printf("请输入第%d个进程信息:
",i+1);
scanf("%s%f%f",&p[i].name,&p[i].arrivetime,&p[i].servicetime);
printf("\n");
}
}
voidPrint(jcb*p,floatarrivetime,floatservicetime,floatstarttime,floatfinishtime,floatzztime,floatavezztime,intN)
{intk;
printf("调度顺序:
");
printf("%s",p[0].name);
for(k=1;k{printf("-->%s",p[k].name);}
printf("\n\n");
printf("\t\t\t进程信息:
\n");
printf("\nname\tarrive\tservice\tstart\tfinish\tzz\tavezz\n");
for(k=0;k<=N-1;k++)
{printf("%s\t%-.2f\t%-.2f\t%-.2f\t%-.2f\t%-.2f\t%-.2f\t\n",p[k].name,p[k].arrivetime,p[k].servicetime,p[k].starttime,p[k].finishtime,p[k].zztime,p[k].avezztime);
}
}
voidsort(jcb*p,intN)
{inti,j;
for(i=0;i<=N-1;i++)
for(j=0;j<=i;j++)
if(p[i].arrivetime
{jcbtemp;
temp=p[i];
p[i]=p[j];
p[j]=temp;
}
}
voiddeal(jcb*p,floatarrivetime,floatservicetime,floatstarttime,floatfinishtime,float&zztime,float&avezztime,intN)
{intk;
for(k=0;k<=N-1;k++)
{if(k==0)
{p[k].starttime=p[k].arrivetime;
p[k].finishtime=p[k].arrivetime+p[k].servicetime;}
else
{p[k].starttime=p[k-1].finishtime;
p[k].finishtime=p[k-1].finishtime+p[k].servicetime;}
}
for(k=0;k<=N-1;k++)
{
p[k].zztime=p[k].finishtime-p[k].arrivetime;
p[k].avezztime=p[k].zztime/p[k].servicetime;
}
}
voidjcbf(jcb*p,intN)
{floatarrivetime=0,servicetime=0,starttime=0,finishtime=0,zztime=0,avezztime=0;
intm,n,next,k,i=0;floatmin;
sort(p,N);
for(m=0;m{
if(m==0)
p[m].finishtime=p[m].arrivetime+p[m].servicetime;
else
p[m].finishtime=p[m-1].finishtime+p[m].servicetime;
for(n=m+1;n<=N-1;n++)
{if(p[n].arrivetime<=p[m].finishtime)
i++;
}
min=p[m+1].servicetime;
next=m+1;
for(k=0;k{if(p[k+1].servicetime{min=p[k+1].servicetime;
next=k+1;}
}
{jcbtemp;
temp=p[m+1];p[m+1]=p[next];p[next]=temp;}
deal(p,arrivetime,servicetime,starttime,finishtime,zztime,avezztime,N);
Print(p,arrivetime,servicetime,starttime,finishtime,zztime,avezztime,N);}
}
intmain()
{intN,*b;charch;
while
(1){
system("CLS");
system("graftabl936");
printf("\t\t\t------短作业优先调度算法------\n");
printf("输入进程个数:
");
scanf("%d",&N);
if(N>MAX){
printf("\t!
!
输入的作业数目太大,请输入不大于%d的整数\n",MAX);
printf("按Q或者q退出程序,按其他任意键继续测试...");
ch=getch();
if(ch=='Q'||ch=='q'){
break;
}
elsecontinue;
}
input(a,N);
jcb*b=a;
jcbf(b,N);
printf("按Q或者q退出程序,按其他任意键继续测试...");
ch=getch();
if(ch=='Q'||ch=='q'){
break;
}
}
return0;
getch();
}
3、可抢占优先权调度算法
#include
#include
#include
#include
#include
#include
typedefcharstring[10];
structtask{
stringname;
intarrTime;
intserTime;
intwaiTime;
intbegTime;
intfinTime;
intturTime;
intwTuTime;
intpriority;
intfinish;
}JCB[10];
intnum;
voidinput()
{
inti;
system("cls");
printf("\n请输入作业数量:
");
scanf("%d",&num);
for(i=0;i{
printf("\n请输入作业NO.%d:
\n",i);
printf("作业名称:
");
scanf("%s",JCB[i].name);
printf("到达时间:
");
scanf("%d",&JCB[i].arrTime);
printf("服务时间:
");
scanf("%d",&JCB[i].serTime);
JCB[i].priority=0;
JCB[i].finish=0;
}
}
intHRN(intpre)
{
intcurrent=1,i,j;
for(i=0;i{
JCB[i].waiTime=JCB[pre].finTime-JCB[i].arrTime;
JCB[i].priority=(JCB[i].waiTime+JCB[i].serTime)/JCB[i].serTime;
}
for(i=0;i{
if(!
JCB[i].finish)
{
current=i;
break;
}
}
for(j=i;j{
if(!
JCB[j].finish)
{
if(JCB[current].arrTime<=JCB[pre].finTime)
{
if(JCB[j].arrTime<=JCB[pre].finTime&&JCB[j].priority>JCB[current].priority)
current=j;
}
else
{
if(JCB[j].arrTimecurrent=j;
if(JCB[j].arrTime==JCB[current].arrTime)
if(JCB[j].priority>JCB[current].priority)
current=j;
}
}
}
returncurrent;
}
voidruning(inti,inttimes,intpre,intstaTime,intendTime)
{
if(times=0)
{
JCB[i].begTime=JCB[i].arrTime;
JCB[i].finTime=JCB[i].begTime+JCB[i].serTime;
JCB[i].turTime=JCB[i].serTime;
JCB[i].wTuTime=1.0;
staTime=JCB[i].begTime;
}
else
{
if(JCB[i].arrTime>JCB[pre].finTime)
JCB[i].begTime=JCB[i].arrTime;
else
JCB[i].begTime=JCB[pre].finTime;
JCB[i].finTime=JCB[i].begTime+JCB[i].serTime;
JCB[i].turTime=JCB[i].finTime-JCB[i].arrTime;
JCB[i].wTuTime=JCB[i].turTime/JCB[i].serTime;
}
if(times==num-1)
endTime=JCB[i].finTime;
JCB[i].finish=1;
}
voidprint(inti,inttimes)
{
if(times==0)
{
printf("名称到达时间服务时间开始时间完成时间周转时间带权周转时间\n");
}
printf("%3s%9d%9d%9d%9d%9d%9d\n",JCB[i].name,JCB[i].arrTime,JCB[i].serTime,JCB[i].begTime,JCB[i].finTime,JCB[i].turTime,JCB[i].wTuTime);
}
voidcheck()
{
inti;
intstaTime,endTime,sumTurTime=0.0,sumWTuTime=0.0,aveturTime,aveWTuTime;
intcurrent=0,times=0,pre=0;
JCB[pre].finTime=0;
for(i=0;i{
JCB[i].finish=0;
}
staTime,endTime,sumTurTime=0.0,sumWTuTime=0.0,aveturTime,aveWTuTime;
current=0;times=0;pre=0;
printf("-------------------------------------------\n");
for(i=0;i{
JCB[i].finish=0;
}
staTime,endTime,sumTurTime=0.0,sumWTuTime=0.0,aveturTime,aveWTuTime;
current=0;times=0;pre=0;
printf("-------HRRN-------------------------------------\n");
for(times=0;times{
current=HRN(pre);
runing(current,times,pre,staTime,endTime);
print(current,times);
pre=current;
}
for(i=0;i{
sumTurTime+=JCB[i].turTime;
sumWTuTime+=JCB[i].wTuTime;
}
aveturTime=sumTurTime/num;
aveWTuTime=sumWTuTime/num;
printf("<计与平均值>%9d%9d%9d%9d\n",NULL,sumTurTime,aveturTime,aveWTuTime);
printf("-------------------------------------------------------\n");
}
voidmain()
{
charagain;
system("graftabl936");
do{
system("cls");
printf("请输入4组数据:
");
input();
check();
printf("Continue...(Y/N):
");
do{
again=getch();
}while(again!
='Y'&&again!
='y'&&again!
='N'&&again!
='n');
}while(again=='Y'||again=='y');
getch();
}
六、运行结果
七、实验总结
1、FCFS算法,即先来先服务,就是每次从就绪队列中选择一个最先进入队列
的进程,把CPU分配给它,令它运行。
该进程一直运行下去,直到完成,或者由于某种原因而阻塞,才会放弃CPU。
FCFS算法比较有利于长作业,而不利于短作业。
另外,FCFS调度算法对CPU繁忙型作业较有利,而不利于I/O繁忙型作业。
2、短作业优先法(SJF),是指分派CPU时,把CPU优先分给最短的作业。
SJF算法在作业调度上用的很多。
它的缺点是对长作业不利,并且不能保证及时处理紧迫性作业。
3、优先权算法指后备作业中选择一批优先权相对高的调入存。
4、最高响应比优先法(HRN)是对FCFS方式和SJF方式的一种综合平衡。
HRN调度策略同时考虑每个作业的等待时间长短和估计需要的执行时间长短,从中选出响应比最高的作业投入执行。
响应比R定义如下:
R=(W+T)/T=1+W/T。
5、作业调度的实现主要有两个问题:
一个是如何将系统中的作业组织起来;另一个是如何进行作业调度。
6、为了将系统中的作业组织起来,需要为每个进入系统的作业建立档案以记录和作业相关的信息,例如,作业名‘作业执行时间、指向下一个作业控制块的指针等信息。
这个记录作业相关信息的数据块称为作业控制块JCB,并将系统中等待作业调度的作业控制块组织成一个队列,这个队列称为后备队列。