操作系统实验报告+进程调度+作业调度等.docx
《操作系统实验报告+进程调度+作业调度等.docx》由会员分享,可在线阅读,更多相关《操作系统实验报告+进程调度+作业调度等.docx(62页珍藏版)》请在冰豆网上搜索。
操作系统实验报告+进程调度+作业调度等
操作系统实验报告
1、进程调度
2、作业调度
3、主存空间的分配与回收
4、文件系统
学生学院______计算机学院______
专业班级____网络工程(3)班_____
学号______********62_____
学生姓名________张菲_______
指导教师_______胡欣如_______
2009年12月20日
计算机学院网络工程专业3班_____组、学号********62
姓名张菲协作者无教师评定_________________
实验题目进程调度
一、实验目的
用高级语言编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解。
二、实验内容和要求
编写并调试一个模拟的进程调度程序,采用“简单时间片轮转法”调度算法对五个进程进行调度。
每个进程有一个进程控制块(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),直到就绪队列为空。
五、流程图
是
六、结果过程及截图
初始化队列
输入所有进程后的进程信息如下:
按Y键继续运行进程:
运行若干次后的状态:
添加新的进程:
七、所遇困难的解决以及心得体会
在这个多级反馈的实验中,我采取了用一条实际上的链表队列来模拟多个逻辑上的队列,通过维护几个链表的状态信息来找到每个进程运行完后应该插入的地方,还有一个标志位Fend用来表明新插入的队列的位置。
虽然实验原理很简单,但是在编写代码的过程中遇到了不少的问题,在两个小时之内已经完成的大体代码的编写,但是之中存在不少的问题,导致了用了差不多四个小时的时间去调试才把它弄好,这主要归咎于在开始设计代码的不太合理,在后期使得代码结构有些混乱,使得调试更加的麻烦,以及对编程的不熟悉。
通过这个实验不仅使我对进程的调度算法有了更深的认识,使得理论知识得到的实践,也使我的编程能力得到了进一步提高。
七、思考题
1、分析不同调度算法的调度策略,比较不同调度算法的优缺点,总结它们的适用范围。
答:
动态有限权算法:
动态优先权是指在创建进程时所创建的优先权,会随进程的推进或者等待时间的增加而改变,以便获得更好的调度性能。
处理机为每个进程分配一定的时间片,在就绪队列中,优先权高的进程将优先获得处理机,进程在进去运行完响应的时间片后,如没完成,优先权减1,从新回到就绪队列等待分配处理机。
时间片的轮转法:
系统将所有进程排成一个队列,按照先来先服务的原则,对队列首的进程进行处理,每个进程在用完自己的时间片后,从新回到队尾进行排队。
每运行一次,进程的需要时间减1,直到就绪队列为空!
八、源代码
#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");
}
while(ch!
='\n'){
if(ch>'9'||ch<'0'){
printf("\t输入有误!
!
输入只能为正整数,请重新输入...\n");
i=0;
}else{
i=i*10+(ch-'0');
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;
voidinsert()//插入进程
ready){
ready=p;
pfend=p;
pinsert=p;
}elseif(ready->queue==1){//第一队列存在
p->link=pfend->link;
pfend->link=p;
findpos();
p->link=ready;
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->queuelink->queue)return;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();} 计算机学院网络工程专业3班_____组、学号3107007062姓名张菲协作者无教师评定_________________实验题目作业调度一、实验目的本实验要求学生模拟作业调度的实现,用高级语言编写和调试一个或多个作业调度的模拟程序,了解作业调度在操作系统中的作用,以加深对作业调度算法的理解。二、实验内容和要求1、编写并调度一个多道程序系统的作业调度模拟程序。 作业调度算法:采用基于先来先服务的调度算法。可以参考课本中的方法进行设计。对于多道程序系统,要假定系统中具有的各种资源及数量、调度作业时必须考虑到每个作业的资源要求。三、实验主要仪器设备和材料硬件环境:IBM-PC或兼容机软件环境:C语言编程环境四、实验原理及设计方案采用多道程序设计方法的操作系统,在系统中要经常保留多个运行的作业,以提高系统效率。作业调度从系统已接纳的暂存在输入井中的一批作业中挑选出若干个可运行的作业,并为这些被选中的作业分配所需的系统资源。对被选中运行的作业必须按照它们各自的作业说明书规定的步骤进行控制。采用先来先服务算法算法模拟设计作业调度程序。(1)、作业调度程序负责从输入井选择若干个作业进入主存,为它们分配必要的资源,当它们能够被进程调度选中时,就可占用处理器运行。作业调度选择一个作业的必要条件是系统中现有的尚未分配的资源可满足该作业的资源要求。但有时系统中现有的尚未分配的资源既可满足某个作业的要求也可满足其它一些作业的要求,那么,作业调度必须按一定的算法在这些作业中作出选择。先来先服务算法是按照作业进入输入井的先后次序来挑选作业,先进入输入井的作业优先被挑选,当系统中现有的尚未分配的资源不能满足先进入输入井的作业时,那么顺序挑选后面的作业。(2)假定某系统可供用户使用的主存空间共100k,并有5台磁带机。3)流程图:五、结果过程及截图读取文件jobs.txt来初始化主存,磁带机的个数,并打印出来。初始时间是9:00:按Y运行5分钟:按Y运行5分钟:按Y运行5分钟:多次运行后最后状态:六、所遇困难的解决以及心得体会这个实验是花的时间最多的一个实验,第一次做的时候由于理解有些问题,所以做错了。之后重新做了一遍,收获还是很多的,遇到了很多的细节问题,例如像是时间化成浮点数和浮点数化成时间等一些问题,从中也暴露了自己的编程能力欠缺,之后要多多的写程序。七、思考题1、写出每种算法的调度策略,最后比较各种算法的优缺点。答:先来先服务算法是根据作业的进入时间来排序,到达时间短的先运行,优点是实现简单,缺点是运行时间慢。短作业优先算法是根椐作业的估计运行时间来排序,估计运行时间短的先运行,优点是运行时间快,缺点是实现起来比较复杂。2、选择调度算法的依据是什么?答:如果作业要求的速度不高,而且作业比较小型,那就最好用先来先服务算法。如果作业要求的速度高,作业流程复杂,那就最好用短作业优先算法。八、源代码#include#include#include#include#definegetjcb()(JCB*)malloc(sizeof(JCB))typedefstruct{//资源的总量intmemory;inttape;}RESOURCE;typedefstructJCB{//作业控制块charusername[20];//用户名charjobname[10];//作业名charstate;//作业状态charatime[5];//到达时间floatrtime;//运行时间RESOURCEresource;//资源数量structJCB*link;}JCB;RESOURCEsource={100,5};JCB*pjcb=getjcb();//作业链表头charnowtime[5];//现在时间,初始时间为9:00FILE*ignore(FILE*fp)//忽略文件中的空白符{if(feof(fp))returnfp;charch=fgetc(fp);while(!feof(fp)&&(ch==''||ch=='')){ch=fgetc(fp);}//if(!feof(fp))returnfp;fseek(fp,-1,SEEK_CUR);returnfp;}FILE*findchar(FILE*fp,charc)//在文件中找到一个字符的位置(读取文件时用){if(feof(fp))returnfp;charch=fgetc(fp);while(!feof(fp)&&(ch!=c)){ch=fgetc(fp);}fseek(fp,-1,SEEK_CUR);returnfp;}voiddestory()//释放链表所占的内存{JCB*p=pjcb->link;while(pjcb){free(pjcb);pjcb=p;if(p)p=p->link;}}floatstof(char*time)//把时间转化为浮点型数{floath=0,m=0;inti=0;while(time[i]!=':'){h=h*10+time[i]-'0';i++;}i++;while(time[i]!='\0'){m=m*10+time[i]-'0';i++;}return(h+m/60);}char*ftos(doubleftime)//把浮点型数值转化为时间{inth,m;h=int(ftime);m=int((ftime-h)*60);sprintf(nowtime,"%c:%c%c",h+'0',int(m/10)+'0',int(m%10)+'0');returnnowtime;} floattimesub(char*time1,char*time2)//两个时间相减,得到时间差{returnstof(time1)-stof(time2);}voidprint()//打印输出{JCB*p=pjcb->link;printf("现在时间是%s\n",nowtime);printf("现在资源的数量%d\t\t%d\n",source.memory,source.tape);printf("\t\t\t\t\t\t\t资源要求\n");printf("用户名\t作业名\t状态\t到达时间\t运行时间(小时)\t主存(K)\t磁带机\n");while(p){printf("%s\t%s\t%c\t%s\t\t\t%.2f\t%d\t%d\n",p->username,p->jobname,p->state,p->atime,p->rtime,p->resource.memory,p->resource.tape);p=p->link;}} voidsendsource()//为作业分配资源{JCB*p;p=pjcb->link;while(p){//为到达的作业调度if(p->state=='W'&&source.memory-p->resource.memory>=0&&source.tape-p->resource.tape>=0){p->state='R';source.memory-=p->resource.memory;source.tape-=p->resource.tape;printf("\n%s\t%s被调入内存\n",p->username,p->jobname);}p=p->link;}} voidinit()//初始化,读取文件中的作业信息{FILE*fp;JCB*p=NULL,*q=pjcb;if((fp=fopen("jobs.txt","r"))==NULL){printf("Cannotopenthefile!");exit(1);}rewind(fp);fp=findchar(fp,'A');while(!feof(fp)){p=getjcb();fscanf(fp,"%s",p->username);fp=ignore(fp);fscanf(fp,"%s",p->jobname);fp=ignore(fp);fscanf(fp,"%c",&p->state);fp=ignore(fp);fscanf(fp,"%s",p->atime);fp=ignore(fp);p->rtime=0;//不初始化则会发生错误,fscanf(fp,"%f",&(p->rtime));fp=ignore(fp);fscanf(fp,"%d",&p->resource.memory);fp=ignore(fp);fscanf(fp,"%d",&p->resource.tape);fp=ignore(fp);q->link=p;q=p;}p->link=NULL;sendsource()
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);
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()//调整进程队列
ready->link||ready->queuelink->queue)return;
p=ready->link;
ready->link=pinsert->link;
pinsert->link=ready;
pinsert=ready;
if(ready&&ready->queue==pinsert->queue){
voidaddnew()//添加新的进程
if(ready->queue!
=1){
(ready->queue)++;
ready->etime*=2;
ready->state='w';
sort();/*调用sort函数*/
input();
voiddestroy()/*建立进程撤销函数(进程运行结束,撤销进程)*/
printf("\n进程[%s]已完成.\n",ready->name);
p=ready;
ready=ready->link;
free(p);
if(ready&&ready->queue==pinsert->queue)
voidrunning()/*建立进程就绪函数(进程运行时间到,置就绪状态)*/
(ready->rtime)++;
ready->etime--;
if(ready->rtime==ready->ntime){
destroy();
return;
}elseif(ready->etime==0){
inttime=2;
for(inti=2;i!
=ready->queue;++i)
time*=2;
ready->etime=time;
voidmain()
while(ready!
printf("\nTheexecutename:
%s\n",ready->name);
ready->state='R';
check();
running();
printf("\n按i键添加新进程....按其他任意键继续运行...");
if(ch=='i'||ch=='I')
addnew();
printf("\n\n进程已经完成\n");
getchar();
计算机学院网络工程专业3班_____组、学号3107007062
实验题目作业调度
本实验要求学生模拟作业调度的实现,用高级语言编写和调试一个或多个作业调度的模拟程序,了解作业调度在操作系统中的作用,以加深对作业调度算法的理解。
1、编写并调度一个多道程序系统的作业调度模拟程序。
作业调度算法:
采用基于先来先服务的调度算法。
可以参考课本中的方法进行设计。
对于多道程序系统,要假定系统中具有的各种资源及数量、调度作业时必须考虑到每个作业的资源要求。
采用多道程序设计方法的操作系统,在系统中要经常保留多个运行的作业,以提高系统效率。
作业调度从系统已接纳的暂存在输入井中的一批作业中挑选出若干个可运行的作业,并为这些被选中的作业分配所需的系统资源。
对被选中运行的作业必须按照它们各自的作业说明书规定的步骤进行控制。
采用先来先服务算法算法模拟设计作业调度程序。
(1)、作业调度程序负责从输入井选择若干个作业进入主存,为它们分配必要的资源,当它们能够被进程调度选中时,就可占用处理器运行。
作业调度选择一个作业的必要条件是系统中现有的尚未分配的资源可满足该作业的资源要求。
但有时系统中现有的尚未分配的资源既可满足某个作业的要求也可满足其它一些作业的要求,那么,作业调度必须按一定的算法在这些作业中作出选择。
先来先服务算法是按照作业进入输入井的先后次序来挑选作业,先进入输入井的作业优先被挑选,当系统中现有的尚未分配的资源不能满足先进入输入井的作业时,那么顺序挑选后面的作业。
(2)假定某系统可供用户使用的主存空间共100k,并有5台磁带机。
3)流程图:
五、结果过程及截图
读取文件jobs.txt来初始化主存,磁带机的个数,并打印出来。
初始时间是9:
00:
按Y运行5分钟:
多次运行后最后状态:
六、所遇困难的解决以及心得体会
这个实验是花的时间最多的一个实验,第一次做的时候由于理解有些问题,所以做错了。
之后重新做了一遍,收获还是很多的,遇到了很多的细节问题,例如像是时间化成浮点数和浮点数化成时间等一些问题,从中也暴露了自己的编程能力欠缺,之后要多多的写程序。
1、写出每种算法的调度策略,最后比较各种算法的优缺点。
先来先服务算法是根据作业的进入时间来排序,到达时间短的先运行,优点是实现简单,缺点是运行时间慢。
短作业优先算法是根椐作业的估计运行时间来排序,估计运行时间短的先运行,优点是运行时间快,缺点是实现起来比较复杂。
2、选择调度算法的依据是什么?
如果作业要求的速度不高,而且作业比较小型,那就最好用先来先服务算法。
如果作业要求的速度高,作业流程复杂,那就最好用短作业优先算法。
#definegetjcb()(JCB*)malloc(sizeof(JCB))
typedefstruct{//资源的总量
intmemory;
inttape;
}RESOURCE;
typedefstructJCB{//作业控制块
charusername[20];//用户名
charjobname[10];//作业名
charstate;//作业状态
charatime[5];//到达时间
floatrtime;//运行时间
RESOURCEresource;//资源数量
structJCB*link;
}JCB;
RESOURCEsource={100,5};
JCB*pjcb=getjcb();//作业链表头
charnowtime[5];//现在时间,初始时间为9:
00
FILE*ignore(FILE*fp)//忽略文件中的空白符
if(feof(fp))returnfp;
charch=fgetc(fp);
while(!
feof(fp)&&(ch==''||ch=='')){
ch=fgetc(fp);
//if(!
feof(fp))returnfp;
fseek(fp,-1,SEEK_CUR);
returnfp;
FILE*findchar(FILE*fp,charc)//在文件中找到一个字符的位置(读取文件时用)
feof(fp)&&(ch!
=c)){
voiddestory()//释放链表所占的内存
JCB*p=pjcb->link;
while(pjcb){
free(pjcb);
pjcb=p;
if(p)
p=p->link;
floatstof(char*time)//把时间转化为浮点型数
floath=0,m=0;
while(time[i]!
=':
'){
h=h*10+time[i]-'0';
i++;
='\0'){
m=m*10+time[i]-'0';
return(h+m/60);
char*ftos(doubleftime)//把浮点型数值转化为时间
inth,m;
h=int(ftime);
m=int((ftime-h)*60);
sprintf(nowtime,"%c:
%c%c",h+'0',int(m/10)+'0',int(m%10)+'0');
returnnowtime;
floattimesub(char*time1,char*time2)//两个时间相减,得到时间差
returnstof(time1)-stof(time2);
voidprint()//打印输出
printf("现在时间是%s\n",nowtime);
printf("现在资源的数量%d\t\t%d\n",source.memory,source.tape);
printf("\t\t\t\t\t\t\t资源要求\n");
printf("用户名\t作业名\t状态\t到达时间\t运行时间(小时)\t主存(K)\t磁带机\n");
while(p){
printf("%s\t%s\t%c\t%s\t\t\t%.2f\t%d\t%d\n",p->username,p->jobname,p->state,p->atime,p->rtime,p->resource.memory,p->resource.tape);
voidsendsource()//为作业分配资源
JCB*p;
p=pjcb->link;
while(p){//为到达的作业调度
if(p->state=='W'&&source.memory-p->resource.memory>=0&&source.tape-p->resource.tape>=0){
p->state='R';
source.memory-=p->resource.memory;
source.tape-=p->resource.tape;
printf("\n%s\t%s被调入内存\n",p->username,p->jobname);
voidinit()//初始化,读取文件中的作业信息
FILE*fp;
JCB*p=NULL,*q=pjcb;
if((fp=fopen("jobs.txt","r"))==NULL){
printf("Cannotopenthefile!
exit
(1);
rewind(fp);
fp=findchar(fp,'A');
feof(fp)){
p=getjcb();
fscanf(fp,"%s",p->username);
fp=ignore(fp);
fscanf(fp,"%s",p->jobname);
fscanf(fp,"%c",&p->state);
fscanf(fp,"%s",p->atime);
p->rtime=0;//不初始化则会发生错误,
fscanf(fp,"%f",&(p->rtime));
fscanf(fp,"%d",&p->resource.memory);
fscanf(fp,"%d",&p->resource.tape);
q->link=p;
q=p;
sendsource()
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1