操作系统实验报告进程调度.docx
《操作系统实验报告进程调度.docx》由会员分享,可在线阅读,更多相关《操作系统实验报告进程调度.docx(17页珍藏版)》请在冰豆网上搜索。
操作系统实验报告进程调度
五邑大学实验报告
操作系统课程
2016~2017年度第1学期
实验题目:
进程调度
院系:
计算机学院
班级:
140801
学号:
3114002472
姓名:
黄凯鑫
任课教师:
白明成绩评定:
实验二题目:
进程调度
完成日期:
2016年12月11日
1、实验目的
(1)设计一个有n个进程工行的进程调度程序。
每个进程由一个进程控制块(PCB)表示。
进程控制块通常应包含下述信息:
进程名、进程优先数、进程需要运行的时间、占用CPU的时间以及进程的状态等,且可按调度算法的不同而增删。
(2)调度程序应包含2~3种不同的调度算法,运行时可任意选一种,以利于各种算法的分析比较。
(3)系统应能显示或打印各进程状态和参数的变化情况,便于观察诸进程的调度过程
2、实验内容
(1)编制和调试示例给出的进程调度程序,并使其投入运行。
(2)自行设计或改写一个进程调度程序,在相应机器上调试和运行该程序,其功能应该不亚于示例。
(3)直观地评测各种调度算法的性能。
3、算法设计
算法:
(1)优先数法。
进程就绪链按优先数大小从高到低排列,链首进程首先投入运行。
每过一个时间片,运行进程所需运行的时间片数减1,说明它已运行了一个时间片,优先数也减3,理由是该进程如果在一个时间片中完成不了,优先级应该降低一级。
接着比较现行进程和就绪链链首进程的优先数,如果仍是现行进程高或者相同,就让现行进程继续进行,否则,调度就绪链链首进程投入运行。
原运行进程再按其优先数大小插入就绪链,且改变它们对应的进程状态,直至所有进程都运行完各自的时间片数。
(2)简单轮转法。
进程就绪链按各进程进入的先后次序排列,进程每次占用处理机的轮转时间按其重要程度登入进程控制块中的轮转时间片数记录项(相当于优先数法的优先数记录项位置)。
每过一个时间片,运行进程占用处理机的时间片数加1,然后比较占用处理机的时间片数是否与该进程的轮转时间片数相等,若相等说明已到达轮转时间,应将现运行进程排到就绪链末尾,调度链首进程占用处理机,且改变它们的进程状态,直至所有进程完成各自的时间片。
实验源代码:
#include
#include
#include
#include
#include
#include
enumstate//进程的状态
{
Ready,
Working,
Finish
};
structpcb//PCB数据结构
{
intpid;
intpriority;
intcputime;
intneedtime;
intround;
stateprocess;
pcb*next;
};
inttimepiece;
pcb*get_process(){//优先数算法--输入进程个数
intproc;
pcb*q;
pcb*t;
pcb*p;
inti=0;
cout<<"InputProcessNumber(1-10):
";
cin>>proc;
while(proc<1||proc>10)
{
cout<"<";
cin>>proc;
}
//cout<!
!
\n\n";
getch();
srand((unsigned)time(NULL));//初始化随机数种子发生器
while(i{
q=(structpcb*)malloc(sizeof(pcb));
q->pid=rand()%10000;
q->needtime=rand()%10+1;
q->cputime=0;
q->priority=rand()%100;
q->process=Ready;
q->next=NULL;//利用随机数生成进程信息
if(i==0)
{
p=q;
t=q;
}
else
{
t->next=q;
t=q;
}//尾插法建立PCB节点
i++;
}//while
returnp;
}
voiddisplay(pcb*p)
{//优先数算法结果输出
cout<<"ProcessID"<<""<<"Cputime"<<""<<"Needtime"<<""<<"Priority"<<""<<"State"<while(p)
{
cout<<""<pid;
cout<<"\t\t";
cout<cputime;
cout<<"\t";
cout<needtime;
cout<<"\t";
if(p->needtime==0)
cout<<"Done";
else
cout<priority;
cout<<"\t\t";
switch(p->process){
caseReady:
cout<<"Ready"<caseWorking:
cout<<"\b\b->Working<-"<caseFinish:
cout<<"Finish"<}
p=p->next;
}
}
intprocess_finish(pcb*q)//判断是否所有进程都已完成,是则返回1
{
intbl=1;
while(bl&&q)
{
bl=bl&&q->needtime==0;
q=q->next;
}
returnbl;
}
voidcpuexe(pcb*q)
{//优先数算法模拟进程执行函数
pcb*t=q;
inttp=-1;
while(q)
{
if(q->process!
=Finish)
{//未完成的进程置Ready,完成的进程置Finish
q->process=Ready;
if(q->needtime==0)
{
q->process=Finish;
}
}
if(tppriority&&q->process!
=Finish)
{//找到下一个优先数最高且未完成的进程
tp=q->priority;
t=q;
}
q=q->next;
}
if(t->needtime!
=0)
{//修改正在执行的进程的信息,并置其状态为Working
t->priority-=3;
if(t->priority<0)t->priority=0;
t->needtime--;
t->process=Working;
t->cputime++;
}
}
voidpriority_cal()
{//优先数算法主控函数
pcb*p;
system("cls");
p=get_process();
intcpu=0;
charkey;
system("cls");
cout<<"CPUTime:
"<display(p);
cout<getch();
while(!
process_finish(p))
{//当不是所有进程都完成时不断执行进程并显示信息
cpu++;
cout<<"CPUTime:
"<cpuexe(p);
display(p);
cout<key=getch();
if(key=='q')exit(0);
}
printf("Allprocessesarefinished!
");
getch();
}
pcb*get_process_round()
{//时间片算法--输入进程个数及CPU时间片
intproc;
pcb*q;
pcb*t;
pcb*p;
inti=0;
cout<<"InputProcessNumber(1-10):
";
cin>>proc;
while(proc<1||proc>10){
cout<"<";
cin>>proc;
}
cout<<"CPUTimePiece(1-5)?
";
cin>>timepiece;
while(timepiece<1||timepiece>5){
cout<"<";
cin>>timepiece;
}
//cout<!
!
\n\n";
getch();
srand((unsigned)time(NULL));//初始化随机数种子发生器
while(iq=(structpcb*)malloc(sizeof(pcb));//利用随机数建立进程信息
q->pid=rand()%10000;
q->needtime=rand()%10+1;
q->cputime=0;
q->round=0;
q->process=Ready;
q->next=NULL;
if(i==0){//尾插法建立PCB节点
p=q;
t=q;
}
else{
t->next=q;
t=q;
}
i++;
}//while
returnp;
}
voidcpu_round(pcb*p,pcb*q){//时间片算法模拟进程执行函数
while(p){
if(p->needtime==0){//完成的进程置Finish,其它置Ready
p->process=Finish;
}
if(p->process==Working){
p->process=Ready;
}
p=p->next;
}
q->cputime+=timepiece;//修改正在执行进程的信息,并置其状态为Working
q->needtime-=timepiece;
if(q->needtime<0){
q->needtime=0;
}
q->round++;
q->process=Working;
}
pcb*get_next(pcb*k,pcb*head)
{//得到下一个应执行的进程
pcb*t;
t=k;
do
{
t=t->next;
}
while(t&&t->process==Finish);
if(t==NULL)
{
t=head;
while(t!
=k&&t->process==Finish)
{
t=t->next;
}
}
returnt;
}
voiddisplay_round(pcb*p){//时间片算法输出结果
cout<<"ProcessID"<<""<<"Cputime"<<""<<"Needtime"<<""<<"Round"<<""<<"State"<while(p){
cout<<""<pid;
cout<<"\t\t";
cout<cputime;
cout<<"\t";
cout<needtime;
cout<<"\t";
cout<round;
cout<<"\t";
switch(p->process){
caseReady:
cout<<"Ready"<caseWorking:
cout<<"\b\b->Working<-"<caseFinish:
cout<<"Finish"<}
p=p->next;
}
}
voidround_cal()
{
pcb*p;
pcb*r;
system("cls");
p=get_process_round();
intcpu=0;
charkey;
system("cls");
cout<<"CPUTime:
"<display_round(p);
cout<getch();
r=p;
while(!
process_finish(p))
{
cpu+=timepiece;
cpu_round(p,r);
r=get_next(r,p);
cout<<"CPUTime:
"<display_round(p);
cout<key=getch();
if(key=='q')exit(0);
}
}
voiddisplay_menu()
{
cout<<"1Priority"<cout<<"2RoundRobin"<cout<<"3Exit"<cout<<"Choice:
";
}
intmain()
{
charkey;
display_menu();
cin>>key;
switch(key)
{
case'1':
priority_cal();break;
case'2':
round_cal();break;
case'3':
exit(0);
}
return0;
}
4、运行与测试
P算法:
输入进程数4以后,由srand函数随机给出各个进程的needtime和priority。
之后寻找priority最大的优先做,做的过程就是将cputime=cputime+1,needtime=needtime-1做完之后将priority=priority-3,再次开始寻找新的高优先级进程。
RR算法:
在输入了进程数3,时间片大小3之后,由srand()函数给出每个函数的needtime。
然后从位置靠前的进程开始,工作3个单位时间的cputime,之后cputime=cputime+3,needtime=needtime-3,若needtime小于3,则置0.,round=round+1.由于同一个时间片只能分配给一个进程,不能分割,因此每个cputime总是时间片大小的整数倍。
5、总结与心得
这个实验在编程上的要求很高,由于在数据结构语法上的不扎实,在实现的时候出处碰壁。
在老师给的参考的帮助下,完成了这个实验。
在实现的过程中,对于书上概念的理解更加深入。
例如pcb在内存中利用链表的数据结构链接,pcb中也有各种进程相关的信息。
在模拟真机进程调度的同时,对每一个进程的每一步变化都很清晰。
在比较这两个算法时,如果时间片过大,就会浪费时间cpu时间(因为在进程的最后可能只需要时间片的前面一小部分),造成资源浪费。
在P算法中,优先级每次减少的数也很关键,若是过小了,不能达到照顾低优先级的小进程的作用,若是过大了,优先级这个属性的作用就不明显了。
具体的取值还要参考优先数的大小和进程needtime的大小。