陈泳鑫3110006379操作系统实验报告.docx
- 文档编号:5762255
- 上传时间:2023-01-01
- 格式:DOCX
- 页数:58
- 大小:1.03MB
陈泳鑫3110006379操作系统实验报告.docx
《陈泳鑫3110006379操作系统实验报告.docx》由会员分享,可在线阅读,更多相关《陈泳鑫3110006379操作系统实验报告.docx(58页珍藏版)》请在冰豆网上搜索。
陈泳鑫3110006379操作系统实验报告
实验
课程名称操作系统
学院计算机学院
专业软件工程
年级班别10级4班
学号3110006379
学生姓名陈泳鑫
指导教师梁路
2013年1月10日
实验一:
进程调度
一、实验目的
用高级语言编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解。
二、实验内容和要求
编写并调试一个模拟的进程调度程序,采用“简单时间片轮转法”调度算法对五个进程进行调度。
每个进程有一个进程控制块(PCB)表示。
进程控制块可以包含如下信息:
进程名、到达时间、需要运行时间、已运行时间、进程状态等等。
进程的到达时间及需要的运行时间可以事先人为地指定(也可以由随机数产生)。
进程的到达时间为进程输入的时间。
进程的运行时间以时间片为单位进行计算。
每个进程的状态可以是就绪W(Wait)、运行R(Run)两种状态之一。
就绪进程获得CPU后都只能运行一个时间片。
用运行时间加1来表示。
如果运行一个时间片后,进程的已占用CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应分配时间片给就绪队列中排在该进程之后的进程,并将它插入就绪队列队尾。
每进行一次调度程序都打印一次运行进程、就绪队列、以及各个进程的PCB,以便进行检查。
重复以上过程,直到所要进程都完成为止。
三、实验主要仪器设备和材料
硬件环境:
IBM-PC或兼容机
软件环境:
C语言编程环境
四、实验原理及设计方案
1、进程调度算法:
采用多级反馈队列调度算法。
其基本思想是:
当一个新进程进入内在后,首先将它放入第一个队列的末尾,按FCFS原则排队等待高度。
当轮到该进程执行时,如能在该时间片内完成,便可准备撤离系统;如果它在一个时间片结束时尚为完成,调度程序便将该进程转入第二队列的末尾,再同样地按FCFS原则等待调度执行,以此类推。
2、实验步骤:
(1)按先来先服务算法将进程排成就绪队列。
(2)检查所有队列是否为空,若空则退出,否则将队首进程调入执行。
(3)检查该运行进程是否运行完毕,若运行完毕,则撤消进程,否则,将该进程插入到下一个逻辑队列的队尾。
(4)是否再插入新的进程,若是则把它放到第一逻辑队列的列尾。
(5)重复步骤
(2)、(3)、(4),直到就绪队列为空。
五、流程图
是
是
六、结果过程及截图
初始化队列
输入所有进程后的进程信息如下:
按任意键继续运行进程:
按任意键继续运行进程:
运行若干次后的状态:
添加新的进程:
七、思考题
1、分析不同调度算法的调度策略,比较不同调度算法的优缺点,总结它们的适用范围。
答:
动态有限权算法:
动态优先权是指在创建进程时所创建的优先权,会随进程的推进或者等待时间的增加而改变,以便获得更好的调度性能。
处理机为每个进程分配一定的时间片,在就绪队列中,优先权高的进程将优先获得处理机,进程在进去运行完响应的时间片后,如没完成,优先权减1,从新回到就绪队列等待分配处理机。
时间片的轮转法:
系统将所有进程排成一个队列,按照先来先服务的原则,对队列首的进程进行处理,每个进程在用完自己的时间片后,从新回到队尾进行排队。
每运行一次,进程的需要时间减1,直到就绪队列为空!
八、源代码
#include
#include
#include
#definegetpch(type)(type*)malloc(sizeof(type))
#defineNULL0
#defineTIME2//时间片长度
typedefstructpcb{//进程管理块
charname[10];//进程名字
charstate;//进程状态
intqueue;//进程所在的队列
intntime;//进程需要运行的时间
intrtime;//进程已经运行的时间
intetime;//进程在本队列可运行的时间片
structpcb*link;
}PCB;
PCB*ready=NULL,*pinsert=NULL,*pfend=NULL,*p=NULL;//就绪队列,进程插入位置的变量
intgeti()//使用户仅能输入整数
{
charch;
inti=0;
fflush(stdin);
ch=getchar();
while(ch=='\n'){
printf("\tf输入不能为空,请重新输入\n");
fflush(stdin);
ch=getchar();
}
while(ch!
='\n'){
if(ch>'9'||ch<'0'){
printf("\t输入有误!
输入只能为正整数,请重新输入:
\n");
fflush(stdin);
i=0;
ch=getchar();
}else{
i=i*10+(ch-'0');
ch=getchar();
}
}
returni;
}
voidfindpos()//更新状态量
{
PCB*ps=pfend;
if(!
ps||!
ps->link||(ps->link->queue-ps->queue)>1)
pinsert=ps;
else{
while(ps->link&&ps->link->queue!
=(pfend->queue+2))
ps=ps->link;
pinsert=ps;
}
}
voidinsert()//插入进程
{
if(!
ready){
ready=p;
pfend=p;
pinsert=p;
}elseif(ready->queue==1){//第一队列存在
p->link=pfend->link;
pfend->link=p;
pfend=p;
findpos();
}
else{
p->link=ready;
ready=p;
findpos();
}
}
voidinput()/*建立进程控制块函数*/
{
inti,num;
printf("\n请输入进程的个数:
");
num=geti();
for(i=0;i { printf("\n进程号No.%d: \n",i+1); p=getpch(PCB); printf("\n输入进程名: "); scanf("%s",p->name); printf("\n输入进程运行时间: "); p->ntime=geti(); printf("\n"); p->rtime=0; p->state='w'; p->queue=1; p->etime=TIME; p->link=NULL; insert();/*调用insert函数*/ } } voiddisp(PCB*pr)/*建立进程现实函数,用于显示当前进程*/ { printf("\nname\tstate\tqueue\tntime\trtime\t在队列可停留时间\t\n"); printf("|%s\t",pr->name); printf("|%c\t",pr->state); printf("|%d\t",pr->queue); printf("|%d\t",pr->ntime); printf("|%d\t",pr->rtime); printf("|%d\t",pr->etime); printf("\n"); } voidcheck()/*建立进程查看函数*/ { PCB*pr; printf("\n当前正在运行的进程是: %s",ready->name);/*显示当前运行的进程*/ disp(ready); pr=ready->link; printf("\n当前就绪队列状态为: \n");/*显示就绪队列状态*/ while(pr! =NULL) { disp(pr); pr=pr->link; } } voidsort()//调整进程队列 { if(! ready->link||ready->queue p=ready->link; ready->link=pinsert->link; pinsert->link=ready; pinsert=ready; ready=p; if(ready&&ready->queue==pinsert->queue){ findpos(); } } voidaddnew()//添加新的进程 { if(ready->queue! =1){ (ready->queue)++; ready->etime*=2; ready->state='w'; sort();/*调用sort函数*/ input(); } else{ input(); } } voiddestroy()/*建立进程撤销函数(进程运行结束,撤销进程)*/ { printf("\n进程[%s]已完成.\n",ready->name); p=ready; ready=ready->link; free(p); if(ready&&ready->queue==pinsert->queue) findpos(); } voidrunning()/*建立进程就绪函数(进程运行时间到,置就绪状态)*/ { (ready->rtime)++; ready->etime--; if(ready->rtime==ready->ntime){ destroy(); return; }elseif(ready->etime==0){ inttime=2; (ready->queue)++; for(inti=2;i! =ready->queue;++i) time*=2; ready->etime=time; ready->state='w'; sort();/*调用sort函数*/ } } voidmain() { charch; input(); while(ready! =NULL) { printf("\nTheexecutename: %s\n",ready->name); ready->state='R'; check(); running(); printf("\n按i键添加新进程/按其他任意键继续运行: "); fflush(stdin); ch=getchar(); if(ch=='i'||ch=='I') addnew(); } printf("\n\n进程已经完成\n"); getchar(); } 实验二: 作业调度 一、实验目的 本实验要求学生模拟作业调度的实现,用高级语言编写和调试一个或多个作业调度的模拟程序,了解作业调度在操作系统中的作用,以加深对作业调度算法的理解。 二、实验内容和要求 作业调度算法: 采用基于先来先服务的调度算法。 可以参考课本中的方法进行设计。 对于多道程序系统,要假定系统中具有的各种资源及数量、调度作业时必须考虑到每个作业的资源要求。 三、实验主要仪器设备和材料 硬件环境: IBM-PC或兼容机 软件环境: C语言编程环境 4、实验原理及设计方案 采用多道程序设计方法的操作系统,在系统中要经常保留多个运行的作业,以提高系统效率。 作业调度从系统已接纳的暂存在输入井中的一批作业中挑选出若干个可运行的作业,并为这些被选中的作业分配所需的系统资源。 对被选中运行的作业必须按照它们各自的作业说明书规定的步骤进行控制。 采用先来先服务算法算法模拟设计作业调度程序。 (1)、作业调度程序负责从输入井选择若干个作业进入主存,为它们分配必要的资源,当它们能够被进程调度选中时,就可占用处理器运行。 作业调度选择一个作业的必要条件是系统中现有的尚未分配的资源可满足该作业的资源要求。 但有时系统中现有的尚未分配的资源既可满足某个作业的要求也可满足其它一些作业的要求,那么,作业调度必须按一定的算法在这些作业中作出选择。 先来先服务算法是按照作业进入输入井的先后次序来挑选作业,先进入输入井的作业优先被挑选,当系统中现有的尚未分配的资源不能满足先进入输入井的作业时,那么顺序挑选后面的作业。 (2)流程图: 五、结果过程及截图 初始化作业,输入时刻,运行时间: 选择1.FCFS算法,执行第一个作业: 执行第二个作业: 执行第三个作业: 完成 初始化作业,输入时刻,运行时间: 选择2.HRN算法,执行第一个作业: 执行第二个作业: 执行第三个作业: 完成: 六、思考题 1、写出每种算法的调度策略,最后比较各种算法的优缺点。 答: 先来先服务算法是根据作业的进入时间来排序,到达时间短的先运行,优点是实现简单,缺点是运行时间慢。 短作业优先算法是根椐作业的估计运行时间来排序,估计运行时间短的先运行,优点是运行时间快,缺点是实现起来比较复杂。 2、选择调度算法的依据是什么? 答: 如果作业要求的速度不高,而且作业比较小型,那就最好用先来先服务算法。 如果作业要求的速度高,作业流程复杂,那就最好用短作业优先算法。 七、源代码 #include"stdio.h" #include #include #definegetpch(type)(type*)malloc(sizeof(type)) #defineNULL0 structworktime{ floatTb;//作业运行时刻 floatTc;//作业完成时刻 floatTi;//周转时间 floatWi;//带权周转时间 }; structjcb{/*定义作业控制块JCB*/ charname[10];//作业名 floatsubtime;//作业提交时间 floatruntime;//作业所需的运行时间 charresource;//所需资源 floatRp;//后备作业响应比 charstate;//作业状态 structworktimewt; structjcb*link;//链指针 }*jcb_ready=NULL,*j; typedefstructjcbJCB; floatT=0; voidsort()/*建立对作业进行提交时间排列函数*/ { JCB*first,*second; intinsert=0; if((jcb_ready==NULL)||((j->subtime)<(jcb_ready->subtime)))/*作业提交时间最短的,插入队首*/ { j->link=jcb_ready; jcb_ready=j; T=j->subtime; j->Rp=1; } else/*作业比较提交时间,插入适当的位置中*/ { first=jcb_ready; second=first->link; while(second! =NULL) { if((j->subtime)<(second->subtime))/*若插入作业比当前作业提交时间短,*/ {/*插入到当前作业前面*/ j->link=second; first->link=j; second=NULL; insert=1; } else/*插入作业优先数最低,则插入到队尾*/ { first=first->link; second=second->link; } } if(insert==0)first->link=j; } } voidHRNget()/*获取队列中的最高响应作业*/ { JCB*front,*mintime,*rear; intipmove=0; mintime=jcb_ready; rear=mintime->link; while(rear! =NULL) if((rear! =NULL)&&(T>=rear->subtime)&&(mintime->Rp)<(rear->Rp)) { front=mintime; mintime=rear; rear=rear->link; ipmove=1; } else rear=rear->link; if(ipmove==1){ front->link=mintime->link; mintime->link=jcb_ready; } jcb_ready=mintime; } voidinput()/*建立作业控制块函数*/ { inti,num; printf("请输入作业数: "); scanf("%d",&num); for(i=0;i { printf("作业号No.%d: ",i); j=getpch(JCB); printf("\n输入作业名: "); scanf("%s",j->name); printf("输入作业提交时刻: "); scanf("%f",&j->subtime); printf("输入作业运行时间: "); scanf("%f",&j->runtime); printf("\n"); j->state='w'; j->link=NULL; sort();/*调用sort函数*/ } } intspace() { intl=0;JCB*jr=jcb_ready; while(jr! =NULL) { l++; jr=jr->link; } return(l); } voiddisp(JCB*jr,intselect)/*建立作业显示函数,用于显示当前作业*/ { if(select==3)printf("\n作业服务时间响应比运行时刻完成时刻周转时间带权周转时间\n"); elseprintf("\n作业服务时间运行时刻完成时刻周转时间带权周转时间\n"); printf("|%s\t",jr->name); printf("|%.2f\t",jr->runtime); if(select==3)printf("|%.2f",jr->Rp); if(j==jr){ printf("|%.2f\t",jr->wt.Tb); printf("|%.2f",jr->wt.Tc); printf("|%.2f\t",jr->wt.Ti); printf("|%.2f",jr->wt.Wi); } printf("\n"); } intdestroy()/*建立作业撤消函数(作业运行结束,撤消作业)*/ { printf("\n作业[%s]已完成.\n",j->name); free(j); return (1); } voidcheck(intselect)/*建立作业查看函数*/ { JCB*jr; printf("\n****当前正在运行的作业是: %s",j->name);/*显示当前运行作业*/ disp(j,select); jr=jcb_ready; printf("\n****当前就绪队列状态为: \n");/*显示就绪队列状态*/ while(jr! =NULL) { jr->Rp=(T-jr->subtime)/jr->runtime; disp(jr,select); jr=jr->link; } destroy(); } voidrunning(JCB*jr)/*建立作业就绪函数(作业运行时间到,置就绪状态*/ { if(T>=jr->subtime)jr->wt.Tb=T;elsejr->wt.Tb=jr->subtime; jr->wt.Tc=jr->wt.Tb+jr->runtime; jr->wt.Ti=jr->wt.Tc-jr->subtime; jr->wt.Wi=jr->wt.Ti/jr->runtime; T=jr->wt.Tc; } intmain()/*主函数*/ { intselect=0,len,h=0; floatsumTi=0,sumWi=0; input(); len=space(); printf("\n\t1.FCFS2.HRN\n\n请选择作业调度算法: "); scanf("%d",&select); while((len! =0)&&(jcb_ready! =NULL)) { h++; printf("\n执行第%d个作业\n",h); j=jcb_ready; jcb_ready=j->link; j->link=NULL; j->state='R'; running(j); sumTi+=j->wt.Ti; sumWi+=j->wt.Wi; check(select); if(select==3&&h printf("\n按任一键继续......\n"); getchar(); getchar(); } printf("\n\n作业已经完成.\n"); printf("\t此组作业的平均周转时间: %.2f\n",sumTi/h); printf("\t此组作业的带权平均周转时间: %.2f\n",sumWi/h); getchar(); } 实验三: 主存空间的分配和回收 一、实验目的 熟悉主存
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 陈泳鑫 3110006379 操作系统 实验 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)