操作系统实习报告文档格式.docx
《操作系统实习报告文档格式.docx》由会员分享,可在线阅读,更多相关《操作系统实习报告文档格式.docx(34页珍藏版)》请在冰豆网上搜索。
![操作系统实习报告文档格式.docx](https://file1.bdocx.com/fileroot1/2022-12/13/70b66578-ac5a-4af9-b9d7-9cb55b40228e/70b66578-ac5a-4af9-b9d7-9cb55b40228e1.gif)
每个进程被分配一个时间段,称作它的时间片,即该进程允许运行的时间。
如果在时间片结束时进程还在运行,则CPU将被剥夺并分配给另一个进程。
如果进程在时间片结束前阻塞或结束,则CPU当即进行切换。
调度程序所要做的就是维护一张就绪进程列表,当进程用完它的时间片后,它被移到队列的末尾。
当一个新进程进入内存后,首先将它放入第一队列的末尾,按FCFS原则排队等待调度.当轮到该进程执行时,如它能在该时间片内完成,便可准备撤离系统;
如果它在一个时间片结束时尚未完成,调度程序便将该进程转入第二队列的末尾,再同样地按FCFS原则等待调度执行;
如果它在第二队列中运行一个时间片后仍未完成,再依次将它放入第三队列,……,如此下去,当一个长作业(进程)从第一队列依次降到第n队列后,在第n队列中便采取按时间片轮转的方式运行.
结论可以归结如下:
时间片设得太短会导致过多的进程切换,降低了CPU效率;
而设得太长又可能引起对短的交互请求的响应变差。
将时间片设为100毫秒通常是一个比较合理的折衷。
优先数调度算法:
优先数调度算法常用于批处理系统中。
在进程调度中,每次调度时,系统把处理机分配给就绪队列中优先数最高的进程。
它又分为两种:
非抢占式优先数算法和抢占式优先数算法。
在非抢占式优先数算法下,系统一旦把处理机分配给就绪队列中优先数最高的进程后,这个进程就会一直运行,直到完成或发生某事件使它放弃处理机,这时系统才能重新将处理机分配给就绪队列中的另一个优先数最高的进程。
在抢占式优先数算法下,系统先将处理机分配给就绪队列中优先数最高的进程度让它运行,但在运行的过程中,如果出现另一个优先数比它高的进程,它就要立即停止,并将处理机分配给新的高优先数进程。
<二>程序结构
本程序整体思路:
程序有三个算法,先来先服务算法,时间片轮转法和优先数算法,所以在main函数中用一个switch分别为这三个算法分配执行入口,以便调用某个算法,每个算法的相关函数都条理分明写在程序主体里。
整个程序分为五大部分:
第一部分:
结构体
这一部分定义了三个结构体,每一个结构体对应的算法,以方便在算法实现的时候清晰条例的运用各参数。
该部分还在末尾就了一个显示程序主题的信息的函数。
第二部分:
先来先服务算法用到的相关函数
<
1>
.函数有voidinput();
voidFCFSJS();
voidPrint();
voidFCFS()。
2>
.函数作用:
voidinput()函数作用是为fir结构体初始化,进程信息输入;
voidFCFSJS()函数作用是计算周转时间和带权周转时间;
voidPrint()函数作用是对结果跟踪打印输出;
voidFCFS()函数作用则是调用voidFCFSJS()和voidPrint()函数。
3>
.函数说明:
主要说明voidFCFSJS()函数,该函数用了两个for循环。
第一个for循环作用是计算完成时间:
(1)当进程的第一个进程时,完成时间=达到时间+服务时间;
(2)当进程不是第一个进程时则,完成时间=上一个进程的完成时间+服务时间。
第二个for循环作用是计算周转时间和带权周转时间:
(1)周转时间=完成时间-达到时间;
(2)带权周转时间=周转时间/服务时间。
第三部分:
时间片轮转法算法用到的相关函数
.函数有structtimel*TimeS();
voidoutput()。
structtimel*TimeS()函数作用是结构体函数,用来确定head的值,以便将head的值送往output函数,作为参数;
voidoutput()函数作用是跟踪输出结果信息。
主要说明structtimel*TimeS()和voidoutput()函数。
(1)structtimel*TimeS()函数,函数中用了一个for循环,for循环里嵌套一对配对的if-else,else里面再嵌套有一对配对的if-else。
第一个对if-else用来判断队列是否为空,为空则执行if后面的语句,不为空则执行else后面的内容,然后在后面的内容中head和rear的值,执行完则就是执行完一次for循环,再经过判断,继续循环,直到i<
N完成循环,返回最后值head。
(2)voidoutput()函数中则主要是对structtimel*TimeS()函数送来的head进行处理,用p->
rest==0来判断是否删除结点,释放内存,输出最后的结果,函数中用了两个配套的if-else,主要是用来对内存释放的处理以及对进程状态的标识。
第四部分:
优先数算法用到的相关函数
.相关函数有voidinit();
intmax_pri_process();
voidshow();
voidPrFS();
voidinit()函数作用是给prior结构体初始化,输入相关进程信息;
intmax_pri_process()函数作用是确定最大优先数进程;
voidshow()函数作用是打印显示实验结果输出过程及最终结果;
voidPrFS()函数作用是优先级计算,确定哪个进程得到服务,标识状态。
主要说明intmax_pri_process()和voidPrFS()函数。
(1).intmax_pri_process()函数用了一个for循环,for循环里用了两个配对的if、elseif。
第一个配对实现过程为:
如果进程的状态为运行状态,则返回-1,否则当满足进程优先数>
原来设定的最大优先数且状态为就绪状态时,就将这个最新得到的优先数赋给max,将进程号赋给e。
第二个配对实现过程为:
如果具有最大优先数的进程的状态为完成状态则返回-1,否则,就将e作为返回值返回。
(2).voidPrFS()函数用了三个for循环,for循环里面嵌套for循环。
具体执行过程为:
第一个for循环用来计算优先数算法在执行中要执行的总的次数,总的次数=歌进程运行的时间和。
第二个for循环里面嵌套第三个for循环,用来计算优先数及状态。
最里面的for循环第一个if,如果进程状态为运行状态则将当前运行进程的优先数减1,剩余的运行时间就在当前运行时间基础上减1;
第二个if,如果运行时间减到0了就把进程的状态标为完成状态,否则状态为就绪状态,显示打印结果,这样最里面的for循环一次循环完成,如此循环直到完成所有循环,然后退到外层循环,继续执行,直到外层循环也完成。
<三>数据结构
本程序中用到的数据结构有
.先来先服务结构体
structfcfs{
charname[10];
intarrivetime;
intservicetime;
intfinishtime;
doubleturnovertime;
doublepowertime;
};
structfcfsfir[80];
<
.时间片轮转法结构体
structtimel{
charname;
intarrivetime;
intruntime;
intrest;
char*state;
structtimel*next;
.优先数调度算法结构体
structpriority{
charname;
intruntime;
intpri;
charstate;
structpriorityprior[MAX];
<四>程序流程图:
main()
showname()
显示工程信息
2
1
switch(choice)
3
优先数在后面紧跟的此页的后的第三页
时间片在后面紧跟的此页的后的第二页
先来先服务在后面紧跟的此页的后的第一页
(注:
由于页面限制,故每个算法分一页画出)
先来先服务
no
yes
k==0?
p[k].finishtime=p[k].arrivetime+p[k].servicetimep[k].
p[k].finishtime=p[k-1].finishtime+p[k].servicetime
k<
a-1?
周转时间p[k].turnovertime=p[k].finishtime-p[k].arrivetime
带权周转时间p[k].powertime=p[k].turnovertime/p[k].servicetime
接最后汇总
时间片
structtimel*TimeS()
head=rear=NULL
分配内存给p
rear==NULL?
t=NULL
q=head
head=pp->
next=NULL
rear=p
q到达时间小于p到达时间
t=q
q=q->
next
q==head?
rear->
next=pp->
next=NULL
p->
next=headhead=p
t->
next=q
i<
N?
returnhead
head!
=NULL
r=p=head
p!
t=head
rest=p->
rest-slice
state="
running"
rest<
rest=0
t!
输出namearrivetimeruntimereststate
t=t->
getchar()
等待回车
rest==0?
p==head?
r=pp->
ready"
p=p->
r->
next=p->
p=r->
r=p
head=p->
nextfree(p)
p=head;
接最后汇总
优先数
max_pri_process()
prior[i].state=='
r'
?
max<
prior[i].pri&
&
R'
return-1
max=prior[i].pri
e=i
MAX?
prior[e].state=='
F'
?
returne
max_pri_process()!
=-1
prior[max_pri_process()].state='
prior[i].pri-=1prior[i].runtime--
prior[i].runtime==0?
prior[i].state='
prior[i].state='
show()
MAX
j<
t
退出程序
五.运行示例及结果分析
先来先服务算法
先来的进程可以得到先服务的权利,后面来的进程要等到先来的进程完成后才能得到服务。
由结果显示,a进程先到,到达的时间为3个时间单位,要求服务的时间为4个时间单位,则
完成时间=到达时间+服务时间,
周转时间=完成时间-到达时间,
带权周转时间=周转时间/服务时间;
b进程到达时间为5个时间单位,要求服务时间为8时间单位,因为a进程先得到服务,完成后才到b,而a完成时间为7时间单位,故
b的完成时间=a的完成时间+b服务的时间
b的周转时间=b的完成时间-b的到达时间,
b的带权周转时间=b的周转时间/b服务的时间;
试验数据证实,先来先服务算法:
先来就可以先得到服务,后到就得等待,直到前面服务的进程完成后才能得到服务。
时间片轮转算法
时间片轮转算法:
各进程在设定好的时间片内轮流得到服务,直到都完成。
实验结果显示,实验中有a,b两个进程,a先进来,b再到,则开始执行算法,时间片为2个时间单位,a要求运行时间为5个时间单位,b要求运行时间为6个时间单位。
第一次显示a开始得到服务,状态为运行状态,b则为就绪状态,a运行2个时间单位后退出排到队尾,状态为就绪状态,轮到b得到服务,则b为运行状态,运行2时间单位退出又排到队尾,状态变为就绪状态;
这时,a又得到服务,又运行,状态为运行状态,如此反复循环,直到a剩下要求的服务rest为0,则完成,而b还有剩余则继续运行,直到b也完成,最后退出。
实验数据表明,时间轮转法:
想得到服务的进程排成一个队列,从队首开始轮流得到服务,然后又回到队尾排队等待下一次的服务,如此循环,直到所有进程都完成。
优先数调度算法
优先数调度算法:
在所有要求得到服务的进程中,优先数高的先得到服务,优先数低的则需要等待。
实验结果显示,现在有a,b两个进程想要得到服务,而a的优先数为3,b的优先数为4,所以b先得到服务。
b得到服务运行一次,则优先数相应减1,剩下运行时间也相应减1,此时,a,b优先数已变为都是3,则a的优先数成了最高的,故a得到服务。
a运行一次优先数相应减1,剩下运行时间也相应减,因为a的优先数已由3减为2,所以又变成b的优先数最高,则b又得到服务。
如此反复循环,直到a剩余运行时间为0,则把a的状态变为完成,b此时还有剩余则继续运行,也直到剩余运行时间为0,才把状态变为完成。
6、心得与体会
通过本次实习,学到的东西很多,我们知道实验的目的是提高动手实践的能力,学以致用这句话说的不错,我们通过书上的理论知识来指导实践,理论指导实践,要学会把所学的知识用于实际操作中,在实践中发现问题,总会遇到各种问题,关键是能自己学会分析问题,解决问题,这样才能培养自己的自学和解决困难的的思维,提升我们的思考能力;
再有,实验的方法不是唯一的,可以通过不同的方法来得到同一个结果,所以,我们不应该满足一个方法来获得实验结果,我们应该尝试用不同的方法。
实验中用到的三个算法,其中先来先服务算法是相对于其他两个算法来说最容易理解的一个,在后备就绪队列中的进程,先来先服务总是把处于队列最前头的进程调用内存,为之分配处理器和资源,使之状态变为运行状态,进行进程运作,直到进程完成才轮到下一个排在后备就绪队列的队首,然后重复上面步骤使之运行,如此反复进行调入,直到最后所有的进程都完成。
于
在先来先服务的基础上,进来的进程排在后备队列中,等轮到了该进程执行时,如果该进程能在指定的时间片里完成,那么就把CPU和资源让出来给下一个即将要求服务的进程,然后撤离,如果该进程不能在指定的时间片内完成或者阻塞或者其他原因不能再继续执行,则时间片轮转法就将其调到第二个后备就绪队列的末尾,等待下一次的指定时间片内的执行,如果在第二次执行运行一个时间片后还没有完成,则将该进程调到第三个后备就绪队列的末尾,如此反复,直到该进程完成。
优先数算法中,将所有的进程排成一个后备就绪队列,然后通过比较所有进程的优先级数,将优先级数最大的那个进程调入,分配处理机和资源,使其执行,本次实习中用到的是抢占式的处理方式,所以在第一轮优先级数最高的进程执行时,如果出现有优先级数比其还高的进程,则该进程就让出处理机和资源给比它优先级数还高的进程,然后将其排到后备就绪队列的末尾,等待下一次优先级数的比较,如果下一次的比较中其优先级数是最高的则再次将其调入执行,如果其优先级数不是最高的则继续等待,直到其优先级数成为最高才能被再次调入,直到后备就绪队列中的所有进程都得于服务完成。
总的来说,实习过程很重要,态度认真,努力把每天的实习任务完成,当然最后的实习成果也很重要,但实习过程中,通过互相学习,互相讨论,可以弥补平时没有注意到的问题,将所学知识巩固加深理解,这样才能把基础打的扎实,才能向更高的层次提升。
参考文献:
1、汤小丹编:
《计算机操作系统》第三版,西安电子科技大学出版社
2、AbrahamSilberschatz编:
《操作系统概念》(第七版)
3、AndrewS.Tanenbaum著:
《设计及实现》(第三版)
4、XX百科
七、源程序清单
#include<
stdio.h>
stdlib.h>
string.h>
math.h>
#defineMAX2
//**********************************《一》结构体*************************************************
//先来先服务结构体
structfcfs{
charname[10];
intservicetime;
intfinishtime;
doubleturnovertime;
//周转时间
doublepowertime;
//带权周转时间
};
structfcfsfir[80];
//定义进程控制块数组
//时间片轮转法结构体
//要求运行时间
//running运行,ready就绪
//优先数调度算法结构体
//优先数
//状态,r-运行,R-就绪,F-结束
voidshowname()
{
//显示版权信息函数
printf("
\n"
);
┏━━━━━━━━━━━━━━━━━━━━━━━┓\n"
┃>
>
进程调度<
┃\n"
┠───────────────────────┨\n"
┃<
2013年秋操作系统实习!
┃\n"
┗━━━━━━━━━━━━━━━━━━━━━━━┛\n"
\n\n"
}
//********************************************************************************************
///*************************************《二》先来先服务**************************************
//fir结构体初始化,信息输入
voidinput(fcfs*p,inta)//a为输入的进程数
{
inti;
------先来先服务调度算法------\n"
输入进程的名字、到达时间和服务时间:
\n比如:
a23\n"
for(i=0;
=a-1;
i++)
{
输入第%d个进程的信息:
i+1);
scanf("
%s%d%d"
&
p[i].name,&
p[i].arrivetime,&
p[i].servicetime);
}
//计算周转时间和带权周转时间
voidFCFSJS(fcfs*p,intarrivetime,intservicetime,intfinishtime,double
turnovertime,double&
powertime,inta)
{intk;
for(k=0;
k++)
if(k==0)
{
p[k].finishtime=p[k].arrivetime+p[k].servicetime;
//第一个进程,完成时间=达到时间+服务时间
}
else
{
p[k].finishtime=p[k-1].finishtime+p[k].servicetime;
//this完成时间=上一个的完成时间+this服务时间
p[k].turnovertime=p[k].finishtime-p[k].arrivetime;
//周转时间=完成时间-达到时间
p[k].powertime=p[k].turnovertime/p[k].servicetime;
//带权周转时间=周转时间/服务时间
//结果跟踪显示输出
voidPrint(fcfs*p,intarrivetime,intservicetime,intfinishtime,doubleturnovertime,doublepowertime,in