处理机管理实验报告.docx
《处理机管理实验报告.docx》由会员分享,可在线阅读,更多相关《处理机管理实验报告.docx(21页珍藏版)》请在冰豆网上搜索。
![处理机管理实验报告.docx](https://file1.bdocx.com/fileroot1/2023-1/9/368785d6-b019-4339-b9c8-ca55d83ba9f6/368785d6-b019-4339-b9c8-ca55d83ba9f61.gif)
处理机管理实验报告
实验报告
课程名称:
操作系统
实验名称:
处理机管理
学号:
学生姓名:
班级:
指导教师:
评分:
实验日期:
2012年11月19日
1、实验目的:
在多道程序或多任务系统中,系统同时处于就绪态的进程有若干个,也就是说能运行的进程数远远大于处理机个数。
为了使系统中的各进程能有条不紊地运行,必须选择某种调度策略,以选择一进程占用处理机。
设计模拟单处理机调度的算法,巩固和加深处理机调度的概念。
2、实验要求
(1)设计一个按优先级调度的算法
(2)按时间片轮转法进行CPU调度
3、实验环境
硬件:
CPU:
AMDQL64内存:
2GB显卡:
ATI4570硬盘:
日立250G
软件:
Windows2000/XP。
开发工具:
VC++6.0。
4、实验内容
1)实现原理
(1)设计一个按优先级调度的算法
进程的优先数由用户自己指定或程序任意设定,且优先级数越低,优先级越高。
调度时,总是选择优先级最高的进程运行。
为了调度方便,设计一个指针指向5个进程排成的就绪队列的第一个进程,另外再设计一个当前运行进程指针,指向当前正运行的进程。
为了采用动态优先级调度,进程每运行一次,其优先级减1。
进程运行最后一次,若剩余的运行时间部位0,且优先级低于就绪队列的进程的优先级,则选择一个高优先级进程抢占CPU;若剩余时间为0,则把它的状态改为完成状态(C),并撤出就绪队列。
若就绪队列部位空,则重复以上操作,直到所有进程为完成状态。
在所涉及的程序中,应有显示或打印语句,以显示或打印每次被选中进程的进程名以及运行一次后进程的变化,就绪队列中的个进程排队情况等。
为5个进程任意确定一组“优先级”和“要求运行时间”,启动处理机调度程序,显示或打印为此选中的进程名以及进程控制块的动态变化过程:
包括进程已运行时间,剩余时间,就绪队列中的进程等。
优先级调度算法:
按照进程的优先级大小来调度。
使高优先级进程或线程得到优先的处理的调度策略称为优先级调度算法。
进程的优先级可以由系统自动地按一定原则赋给它,也可由系统外部来进行安排但在许多采用优先级调度的系统中,通常采用动态优先数策略。
即一个进程的优先级不是固定的,往往是随许多因素的变化而变化。
尤其随作业(进程)的等待时间,已使用的处理器时间或其他系统资源的使用情况而定,以防止低优先级进程或线程长期饥饿现象发生时间片轮转算法:
时间片轮转算法主要用于处理器调度。
采用此算法的系统,其进程就绪队列往往按进程到达的时间来排序。
进程调度程序总是选择就绪队列中的第一个进程,也就是说按照先进先出原则调度,但一旦进程占有处理器仅使用一个时间片,在使用完一个时间片后,进程还没有完成其运行,它也必须释放出(被抢占)处理器给下一个就绪的进程。
而被抢占的进程返回到就绪队列的末尾重新排队等候再次运行。
(2)按时间片轮转法进行CPU调度。
编写并调试一个模拟的进程调度程序,采用“简单时间片轮转法”进行CPU调度。
每个进程有一个进程控制块(PCB)表示。
进程控制块可以包含如下信息:
进程名、到达时间、需要运行时间、已运行时间、进程状态等等。
进程的到达时间及需要的运行时间可以事先人为地指定(也可以由随机数产生)。
进程的到达时间为进程输入的时间。
进程的运行时间以时间片为单位进行计算。
每个进程的状态可以是就绪W(Wait)、运行R(Run)两种状态之一。
就绪进程获得CPU后都只能运行一个时间片。
用运行时间加1来表示。
如果运行一个时间片后,进程的已占用CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应分配时间片给就绪队列中排在该进程之后的进程,并将它插入就绪队列队尾。
每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的PCB,以便进行检查。
重复以上过程,直到所要进程都完成为止。
进程调度算法:
采用多级反馈队列调度算法。
其基本思想是:
当一个新进程进入内在后,首先将它放入第一个队列的末尾,按FCFS原则排队等待高度。
当轮到该进程执行时,如能在该时间片内完成,便可准备撤离系统;如果它在一个时间片结束时尚为完成,调度程序便将该进程转入第二队列的末尾,再同样地按FCFS原则等待调度执行。
2)程序结构
定义结构体PCB描述进程的进程控制块,定义数组PCBpcb[Max]存放进程进程调度程序调用face()函数选择所要进行的操作。
输入1则增加进程并调度进程,输入2则打印进程,输入0则任务结束增加进程,调用AddProcess()函数,将输入的进程存放在数组pcb[Max]中打印进程,调用print()函数,在该函数中首先调用sort()函数对进程按优先级和先来先服务排序,然后显示输出排序后的进程进程调度,调用attemper()函数,调度优先级最高的进程分配给CPU使之运行一个时间片进程优先级排序,调用sort()函数,按照先来先服务和优先级排序,使排序完最优先运行的进程存放在pcb[0]中。
3)数据结构
1.按优先数调度算法
假定系统有五个进程每一个进程用一个进程控制块PCB来代表,进程控制块的格式为:
进程名
链接指针
进程的优先级
估计运行时间
进程状态
2.按时间片轮转法调度的算法
假定系统有五个进程每一个进程用一个进程控制块PCB来代表,进程控制块的格式为:
进程名
链接指针
到达时间
估计运行时间
进程状态
为每个进程任意确定一个要求运行时间和到达时间,按照进程到达的先后顺序排成一个循环队列,再设一个队首指针指向第一个到达进程的首址。
执行处理机调度时,开始选择队首的第一个进程运行,再设一个当前运行进程指针,指向当前正运行的程序。
进程运行给最后一次,以后的调度则将当前指针一次下移一个位置,指向下一个进程,同时还应该判断该进程的剩余时间运行是否为0.
若就绪队列不为空,则重复上诉操作指导所有进程都运行完为止。
在所涉及的程序中,应有显示或打印语句,以显示或打印每次被选中进程的进程名以及运行一次后进程的变化情况等。
4)实现步骤
(1)打开VC,选择菜单项文件->新建,输入相关程序。
按优先级调度的算法:
按时间片轮转法进行CPU调度:
(2)最后在进行编译连接。
并把实验结果截图保存。
5、实验测试及分析:
按优先级调度的算法:
按时间片轮转法进行CPU调度:
6、实验心得体会
通过这次实验,使我对进程的优先级调度有了一定的了解。
也使我能够很好得了解进程的运行状况,实验中也用到了时间片调度,各个进程分别占用CPU使用权。
附录:
源代码
按优先级调度的算法:
#include
#include
#include
#include
#include
#include
usingnamespacestd;
voiddisplay();//声明函数
intquantity;
typedefstructprocess
{
charpname[20];//进程名
structprocess*next;
intBurstTime;//所需时间
intpriority;//数字越大优先级越高
charStatus;
}PROCESS;
voidinsert(PROCESS*head,PROCESS*p)//入队函数
{
PROCESS*h;
if(head->next==NULL)
{
head->next=p;
p->next=NULL;
}
else
{
h=head;
while(h->next!
=NULL)
{
if((h->next)->priority>=p->priority)
h=h->next;
else
{
p->next=h->next;
h->next=p;
break;
}
}
if(h->next==NULL)
{
h->next=p;
p->next=NULL;
}
}
}
PROCESS*create()//进程初始化
{
PROCESS*q,*h;
inti,num;
h=(structprocess*)malloc(sizeof(structprocess));
h->next=NULL;
cout<<"------请输入进程数目:
";
cin>>num;
for(i=1;i<=num;i++)
{
q=(structprocess*)malloc(sizeof(structprocess));
cout<<"输入第"<
"<cin>>q->pname>>q->BurstTime>>q->priority;
q->Status='R';
q->next=NULL;
insert(h,q);
}
cout<<"就绪队列:
\n";
cout<<"进程名所需时间优先数进程状态\n";
q=h->next;
while(q)
{
q->Status='R';
cout<<""<pname<<""<BurstTime<<""<priority<<""<Status<q=q->next;
}
returnh;
}
voidrun(PROCESS*pt)
{
if(pt->next!
=NULL)
{
PROCESS*q;
cout<<"********************************************"<cout<<"运行一次后:
"<pt->next->priority--;
pt->next->BurstTime--;
if(pt->next->BurstTime==0)
{
pt->next->Status='E';
cout<<"进程名为"<next->pname<<"的进程:
已执行完!
"<<"进程状态:
"<next->Status<q=pt->next;
pt->next=q->next;
free(q);
}
else
{
if(pt->next->next!
=NULL)
{
q=pt->next;
pt->next=q->next;
insert(pt,q);
pt->next->Status='Z';
pt->next->next->Status='R';
}
else
{
q=pt->next;
pt->next=q->next;
insert(pt,q);
pt->next->Status='Z';
}
PROCESS*l;
l=pt->next;
cout<while(l)
{
cout<pname<<""<BurstTime<<""<priority<<""<Status;
l=l->next;
}
}
}
else
{
cout<cout<<"所有进程全部运行完毕!
";
}
cout<charch;
if(pt->next)
{
cout<";
cin>>ch;
if(ch=='Y'||ch=='y')
{
run(pt);
}
if(ch=='C'||ch=='c')
{
PROCESS*q;
q=(structprocess*)malloc(sizeof(structprocess));//先前放在了while前面,不能创建链表进行插入
cout<<"添加进程名"<<"所需时间"<<"优先数"<cin>>q->pname>>q->BurstTime>>q->priority;
insert(pt,q);
cout<<"**********************************"<cout<<"按优先级排列后:
"<cout<q=pt->next;
while(q)
{q->Status='R';
cout<pname<<""<BurstTime<<""<priority<<""<Status;
q=q->next;
}
charch;
if(pt->next)
{
cout<";
}
cin>>ch;
if(ch=='Y'||ch=='y')
{
run(pt);
}
}
}
}
voidmain()
{
PROCESS*head;
head=create();
if(head!
=NULL)
run(head);
cout<<"结束程序"<}
按时间片轮转法进行CPU调度:
/*源程序cpu_time.cpp,采用时间片轮转法在VisualC++6.0下调试运行*/
/*数据结构定义及符号说明*/
#defineN20
#include
#include
typedefstructpcb/*进程控制块定义*/
{
charpname[N];/*进程名*/
intruntime;/*运行时间*/
intarrivetime;/*到达时间*/
charstate;/*进程状态*/
structpcb*next;/*连接指针*/
}PCB;
PCBhead_input;
PCBhead_run;
PCB*pcb_input;
staticcharR='r',C='c';
unsignedlongcurrent;/*记录系统当前时间的变量*/
voidinputprocess();/*建立进程的函数*/
intreadyprocess();/*建立就绪队列函数*/
intreadydata();/*判断是否有就绪进程的函数*/
intrunprocess();/*运行进程的函数*/
FILE*f;
/*定义建立就绪队列函数*/
intreadyprocess()
{
while
(1)
{
if(readydata()==0)/*判断是否就绪函数*/
return1;
else
runprocess();/*运行进程函数*/
}
}
/*定义判断就绪队列是否有进程函数*/
intreadydata()
{
if(head_input.next==NULL)
{
if(head_run.next==NULL)
return0;
else
return1;
}
PCB*p1,*p2,*p3;
p1=head_run.next;
p2=&head_run;
while(p1!
=NULL)
{
p2=p1;
p1=p2->next;
}
p1=p2;
p3=head_input.next;
p2=&head_input;
while(p3!
=NULL)
{
if(((unsignedlong)p3->arrivetime<=current)&&(p3->state==R))
{
printf("Timesliceis%8d(time%4d);Process%sstart,\n",
current,(current+500)/1000,p3->pname);
fprintf(f,"Timesliceis%8d(time%4d);Process%sstart,\n",
current,(current+500)/1000,p3->pname);
p2->next=p3->next;
p3->next=p1->next;
p1->next=p3;
p3=p2;
}
p2=p3;
p3=p3->next;
}
return1;
}
intrunprocess()/*定义运行程序函数*/
{
PCB*p1,*p2;
if(head_run.next==NULL)/*运行队列为空时,修改当前时间*/
{
current++;
return1;
}
else
{
p1=head_run.next;
p2=&head_run;
while(p1!
=NULL)
{
p1->runtime--;
current++;
if(p1->runtime<=0)
{
printf("Timesliceis%8dtime%4d;Process%send.\n",current,(current+500)/1000,p1->pname);
fprintf(f,"Timesliceis%8dtime%4d;Process%send.\n",current,(current+500)/1000,p1->pname);
p1->state=C;
p2->next=p1->next;
deletep1;
p1=NULL;
}
else
{
p2=p1;
p1=p2->next;
}
}
return1;
}
}
/*--定义建立进程函数*/
voidinputprocess()
{
PCB*p1,*p2;
intnum;/*要建立的进程数量*/
unsignedlongmax=0;
printf("Howmanyprocessesdoyouwanttorun:
");
fprintf(f,"Howmanyprocessesdoyouwanttorun:
");
scanf("%d",&num);
fprintf(f,"%d\n",&num);
p1=&head_input;
p2=p1;
p1->next=newPCB;
p1=p1->next;
for(inti=0;i{
printf("InputNO.%3dProcessinputpname:
",i+1);
fprintf(f,"InputNO.%3dProcessinoutpname:
",i+1);
scanf("%s",p1->pname);
fprintf(f,"%s\n",p1->pname);
printf("runtime:
");
fprintf(f,"runtime:
");
scanf("%d",&(p1->runtime));
fprintf(f,"%d\n",&(p1->runtime));
printf("arrivetime:
");
fprintf(f,"arrivetime:
");
scanf("%d",&(p1->arrivetime));
fprintf(f,"%d\n",&(p1->arrivetime));
p1->runtime=(p1->runtime)*1000;
p1->arrivetime=(p1->arrivetime)*1000;
p1->state=R;
if((unsignedlong)(p1->arrivetime)>max)
max=p1->arrivetime;
p1->next=newPCB;
p2=p1;
p1=p1->next;
}
deletep1;
p1=NULL;
p2->next=NULL;
}
/*——定义建立进程函数*/
voidinputprocess1()
{
PCB*p1;
intnum;/*要建立的进程数*/
unsignedlongmax=0;
printf("Howmanyprocessesdoyouwanttorun:
");
fprintf(f,"Howmanyprocessesdoyouwanttorun:
");
scanf("%d",&num);
fprintf(f,"%d\n",&num);
pcb_input=newPCB;
p1=pcb_input;
for(inti=0;i{
printf("NO.%3dprocessinputpname:
",i+1);
fprintf(f,"NO.%3dprocessinputpname:
",i+1);
scanf("%s",p1->pname);
fprintf(f,"%s\n",p1->pname);
printf("runtime:
");
fprintf(f,"runtime:
");
scanf("%d",&(p1->runtime));
fprintf(f,"%d\n",&(p1->runtime));
printf("arrivetime:
");
fprintf(f,"arrivetime:
");
scanf("%d",&(p1->arrivetime));
fprintf(f,"%d\n",&(p1->arrivetime));
//p1->runtime=(p1->runtime)
//p1->arrivetime=(p1->arrivetime);
p1->runtime=(p1->runtime)*1000;
p1->arrivetime=(p1->arrivetime)*1000;
p1