实验一进程控制和调度.docx
《实验一进程控制和调度.docx》由会员分享,可在线阅读,更多相关《实验一进程控制和调度.docx(18页珍藏版)》请在冰豆网上搜索。
实验一进程控制和调度
太原工业学院计算机工程系
实验报告
课程名称
操作系统
班级
11
实验日期
2013-12-04
姓名
学号
24
实验成绩
实验名称
进程控制和调度
实验
目的
及
要求
用高级语言编写和调试进程调度的模拟程序,以加深对进程调度算法的理解。
实
验
环
境
MicrosoftVisualStudio
实
验
内
容
1、自定义进程相关的数据结构;
2、利用MFC类库中的栈(queue),链表(list),向量(vector)等模板模拟进程控制块队列、进程控制块优先级队列、统计信息链表及其指令集合;
3、利用MSDN和MFCAPI编程实现常见的进程控制和调度策略(先来先服务算法(FCFS调度法)、短作业(进程)优先调度算法(SJ调度算法)、最高优先权优先调度算法(优先调度算法)、时间片轮转算法(RR调度算法));
4、测试以上进程调度策略的周转时间、带权周转时间、平均周转时间和平均带权周转时间,并定性评价它们的性能。
算
法
描
述
及
实
验
步
骤
创建和显示进程状态算法:
PCB*CreatPCB(intn)
FCFS调度算法
功能:
根据进程到达的顺序进行调度,先到达的进程先执行。
在就绪队列中排的越靠前越先执行
算法:
voidFCFS(PCB*head,PCB*over)
SJ调度算法
功能:
从就绪队列中选出剩余执行时间最短的就绪进程进行执行。
执行结束后继续从就绪队列中选出剩余执行时间最短的。
直到所有进程都被执行完。
算法:
voidSJF(PCB*head,PCB*over)//sjf算法
优先调度算法(Prio):
功能:
从就绪队列中选出优先级别最高的进程进行执行。
重复进行。
直到所有的所有的进程执行完毕。
算法:
voidPrio(PCB*head,PCB*over)
RR调度算法:
功能:
根据时间片的大小,对每个进程依次执行。
时间片用完之后进程进入阻塞的状态,重新得到时间片后接着执行。
直到完成。
算法:
voidRR(PCB*head,PCB*over,intt,intk)//时间片轮转法
调
试
过
程
及
实
验
结
果
先来先服务算法(FCFS调度法):
短作业(进程)优先调度算法(SJ调度算法):
最高优先权优先调度算法(优先调度算法):
时间片轮转算法(RR调度算法):
总
结
优点:
程序中的数组采用了动态开辟的方法,有效地减少了对于空间的占用。
提高了空间的利用率。
输出的界面比较的简洁,直接给出了分配资源的顺序。
资源请求算法则直接给出了请求后造成的情况,比较的明了。
缺点:
程序仍然存在很多地方可以改进。
比如输出界面,可以做的更漂亮。
部分地方可以采用其他的方法。
附
录
#include
#include
#defineReady0
#defineRunning1
#defineBlock3
#defineOver4
typedefstructPCBNode
{
intID;
intPriority;
intCPUtime;
intAlltime;
intArrivetime;
intstate;
intcounter;
structPCBNode*next;
}PCB;//定义数据结构
PCB*run;
PCB*ready;
PCB*over;
PCB*head;
//定义状态量
intMin(PCB*head)//挑选出队列中的拥有最小alltime值的块,返回块号,用于sjf算法
{
PCB*p;//q用来记录这个块的地址
intmin,id;//记录最小值和块号
p=head->next;
if(p)
{
min=p->Alltime;
id=p->ID;
while(p->next)
{
if(min>p->next->Alltime)
{
min=p->next->Alltime;
id=p->next->ID;
p=p->next;
}
else
{
p=p->next;
}
}
}
returnid;
}
intMax(PCB*head)//挑选出队列中的拥有最大优先级的块,返回块号,用于prio算法
{
PCB*p;//q用来记录这个块的地址
intmax,id;//记录最大和块号
p=head->next;
if(p)
{
max=p->Priority;
id=p->ID;
while(p->next)
{
if(max<=p->next->Priority)
{
max=p->next->Priority;
id=p->next->ID;
p=p->next;
}
else
{
p=p->next;
}
}
}
returnid;
}
PCB*CreatPCB(intn)
{
inti;
PCB*p,*q;
head=(PCB*)malloc(sizeof(PCB));
head->next=NULL;
p=head;
for(i=1;i<=n;i++)
{
q=(PCB*)malloc(sizeof(PCB));
q->ID=i;
q->CPUtime=0;
q->Alltime=rand()%200;
q->Priority=rand()%10;
q->state=Ready;
q->Arrivetime=0;
p->next=q;
p=q;
q->next=NULL;
}
head->next->Priority=0;
returnhead;
}//创建pcb块
voidDisplay(PCB*head)
{
PCB*p;
p=head->next;
printf("IDArrivetimeCPUtime(已占用)AlltimePrioritystate\n");
while(p)
{
printf("%d",p->ID);
printf("%d",p->Arrivetime);
printf("%d",p->CPUtime);
printf("%d",p->Alltime);
printf("%d",p->Priority);
printf("%d\n",p->state);
p=p->next;
}
}//显示PCB块
voidFCFS(PCB*head,PCB*over)
{
PCB*p,*q;
intj=0;
intn=0,s=0;
doublem;
ready=head;
p=ready->next;
q=over;
while(p)
{
p->state=Running;
ready->next=p->next;
n=p->Alltime+n;
p->CPUtime=p->Alltime;
p->Alltime=0;
s=s+n;
p->next=NULL;
q->next=p;
p->state=Over;
q=q->next;
q->next=NULL;
p=head->next;
j++;
printf("第%d次执行算法后的就绪队列:
\n",j);
Display(head);
}
m=(double)s/j;
printf("完成顺寻为:
\n");
Display(over);
printf("\n");
printf("每个进程等待的平均时间为:
%lf\n",m);
printf("所有进程等待的总时间为:
%d",s);
}
voidSJF(PCB*head,PCB*over)//sjf算法
{
PCB*p,*q,*b,*o;//b用来记录该块的地址
ints;//记录块号
intm,n,h=0,d=0,j=0;
doublef;
p=head->next;
q=over;
o=head;
printf("完成顺寻为:
\n");
m=p->ID;
n=p->Alltime;
s=Min(head);
b=p->next;
printf("%d:
\n",s);
while(head->next)
{
while(s!
=p->ID)
{
o=p;
p=p->next;
}
d=p->Alltime+d;
p->CPUtime=p->Alltime;
p->Alltime=0;
h=d+h;
b=p;
q->next=b;
o->next=p->next;
p=head->next;
b->next=NULL;
o=head;
q=q->next;
s=Min(head);
j++;
printf("第%d次执行算法后的就绪队列:
\n",j);
Display(head);
}
f=(double)h/j;
printf("完成顺寻为:
\n");
Display(over);
printf("每个进程等待的平均时间为:
%lf\n",f);
printf("所有进程等待的总时间为:
%d",h);
}
voidPrio(PCB*head,PCB*over)
{
PCB*p,*q,*b,*o;//b用来记录该块的地址
ints;//记录块号
intm,n,h=0,d=0,j=0;
doublef;
p=head->next;
o=head;
q=over;
printf("当前拥有最大优先级的块号为:
\n");
m=p->ID;
n=p->Alltime;
s=Max(head);
b=p->next;
printf("%d:
\n",s);
while(head->next)
{
while(s!
=p->ID)
{
o=p;
p=p->next;
}
d=p->Alltime+d;
p->CPUtime=p->Alltime;
p->Alltime=0;
h=d+h;
b=p;
q->next=b;
o->next=p->next;
p=head->next;
b->next=NULL;
o=head;
q=q->next;
s=Max(head);
j++;
printf("第%d次执行算法后的就绪队列:
\n",j);
Display(head);
}
f=(double)h/j;
printf("完成顺寻为:
\n");
Display(over);
printf("每个进程等待的平均时间为%lf\n",f);
printf("所有进程等待的总时间为:
%d",h);
}
voidRR(PCB*head,PCB*over,intt,intk)//时间片轮转法
{//k用来记录剩余要执行的进程数目
PCB*p,*q,*r,*o,*tail;//o用来记录当前块的地址
intn=0,s=0,f;
doubleh;
f=k;
p=head->next;
while(p->next)
{
tail=p;
p=p->next;
}
printf("执行顺序为:
\n");
tail=p;
o=p;//前驱
tail->next=head->next;
p=head->next;
q=over;
while(k>0)
{
r=head->next;
if(p->Alltime>t)//该进程还未执行完成
{
p->Alltime=p->Alltime-t;
n=n+t;
s=s+n;
o=p;
printf("执行进程%d",p->ID);
printf("该进程的Alltime变为%d\n",p->Alltime);
p=p->next;
}
else//该进程可以完成了
{
printf("完成进程:
%d\n",p->ID);
n=n+p->Alltime;
s=s+n;
p->Alltime=0;
o->next=p->next;
q->next=p;
q=q->next;
q->next=NULL;
p=o->next;
k--;
}
}
h=(double)s/f;
printf("完成顺寻为:
\n");
Display(over);
printf("每个进程等待的平均时间为:
%lf\n",h);
printf("所有进程等待的总时间为:
%d",s);
}
voidmain()
{
intn,m,t;
printf("|------------------------------------------------------------------------------|");
printf("|进程调度的模拟|");
printf("|------------------------------------------------------------------------------|");
printf("\t\t\t|----选项--------------------|\n");
printf("\t\t\t|1.FCFS调度法|\n");
printf("\t\t\t|----------------------------|\n");
printf("\t\t\t|2.SJF调度算法|\n");
printf("\t\t\t|----------------------------|\n");
printf("\t\t\t|3.优先调度算法|\n");
printf("\t\t\t|----------------------------|\n");
printf("\t\t\t|4.RR调度算法|\n");
printf("\t\t\t|----------------------------|\n");
printf("\n");
printf("请输入要创建的进程数目:
");
scanf("%d",&n);
head=CreatPCB(n);
printf("创建的就绪队列为:
\n");
Display(head);
printf("请选择要进行的操作:
");
scanf("%d",&m);
over=(PCB*)malloc(sizeof(PCB));
over->next=NULL;
switch(m)
{
case1:
system("CLS");
FCFS(head,over);
break;
case2:
system("CLS");
SJF(head,over);
break;
case3:
system("CLS");
Prio(head,over);
break;
case4:
system("CLS");
printf("请输入时间片的大小:
");
scanf("%d",&t);
RR(head,over,t,n);
break;
}
//Release(head);
}