操作系统大作业.docx
《操作系统大作业.docx》由会员分享,可在线阅读,更多相关《操作系统大作业.docx(27页珍藏版)》请在冰豆网上搜索。
操作系统大作业
2013-2014学年度第一学期大作业
课程名称:
计算机操作系统
任课教师:
作业题目:
作业调度模拟
姓 名:
学号:
专业:
计算机科学与技术
教学中心:
华南理工深圳宝安教学中心
联系电话:
评审日期__________成绩_________评审教师(签名)__________
华南理工大学网络教育学院
摘要
本文通过C语言程序在LINUX环境下来模拟作业调度中的短作业优先,先来先服务,时间片轮换调度算法,通过程序控制来查看以上三种算法调度的详细过程。
关键词:
作业调度,先来先服务,短作业优先,时间片轮换调度,LINUX
目录
引言……...………………………………………………………………………………….......4
1课题的目的及意义……………………………………………………………………………...5
1.1课题的目的………………………………………………………….……………........5
1.2课题的意义…………………………………………………………..……………........5
2先来先服务和短作业优先的基本思路……………………………………………………....6
2.1基本思路………………………………………………………………………...…........6
2.2数据结构……………………………………………………………………...……........6
2.3程序流程……………………………………………………………………...……........6
2.3算法伪代码……………………………………………………………………...…........7
3算法的程序实现……………………………………………………………………………….8
3.1先来先服务…………………………………………………..……………………….....9
3.2短作业优先………………………………………………………...…………………..10
3.3时间片轮换调度.............................................................................................................13
4先来先服务和短作业优先算法的利弊分析……………………………………....…..14
结束语……………………………………………………………………………………….…...15
参考文献………………………………………………………………………………….……...16
附录……………………………………………………………………………………………....26
引言
作业调度的主要功能是根据作业控制块中的信息,审查系统能否满足用户作业的资源需求,以及按照一定的算法,从外存的后备队列中选取某些作业调入内存,并为它们创建进程、分配必要的资源。
然后再将新创建的进程插入就绪队列,准备执行。
常用的作业调度算法有先来先服务(FCFS)、短作业优先(SJF)、时间片轮转法(RoundRobin)、多级反馈队列算法(RoundRobinwithMultipleFeedback)、优先级算法(PriorityScheduling)、最高响应比优先法(HighestResponse_ratioNext)。
作业调度算法的实现对操作系统合理的分配资源以及进程的创建很重要,好的作业调度算法能够很好的将系统的各类资源充分合理的利用,从而提高了系统资源的使用率、是系统能够更高效的运行。
1课题的目的及意义
1.1课题的目的
通过C语言程序模拟理想状态下作业调度算法中的先来先服务和短作业优先算法来加深对操作系统中作业调度算法的理解。
1.2课题的意义
1、理论意义
学习和理解操作系统中作业调度算--先来先服务和短作业优先算法的工作原理以及实现过程,加深我们对日常使用的操作系统的深层次理解。
2、现实意义
通过使用程序设计语--C语言来模拟理想状态下作业调度算法中先来先服务和短作业优先的实现过程来加深对操作系统的理解,同时也使提升我们的编程能力。
2.先来先服务和短作业优先的基本思路
2.1基本思路
先来先服务调度算法:
将用户作业和就绪进程按提交顺序或变成就绪状态的先后排成队列,优先考虑在系统中等待时间最长的作业,而不管其要求运行时间的长短。
一旦一个进程获得了中央处理机,就一直运行到结束,在理想状态下考虑在第一个作业进入时系统当前没有其他作业正在执行。
短作业优先调度算法:
对预计执行时间最短的作业优先分派处理机,在理想情况下考虑所有作业在同一时刻进入系统。
2.2数据结构
1、在理想情况下将每个作业用一个结构体来存储其对应的信息,并将各个结构体用结构体数组的形式组织到一起。
2、在每个结构体中将作业的作业名、进入时间、运行时间、周转时间、带权周转时间全部存入,并事先将这些信息存入一个txt文本文档中。
2.3程序流程
先来先服务
作业1
作业2
作业3
新作业
作业队列
进入
N
Y
等待队列
短作业优先
2.4算法的伪代码
先来先服务算法
for(i=0;iifi==0(如果当前作业是第一个进入系统的作业)
作业开始执行
ifproc[i].StartTime作业等待,直到正在运行的作业运行完毕为止
短作业优先算法
for(i=0;ifor(i=0;iproc[i].RunTime=proc[i].NeedTime+WaitTime(当前作业的周转时间等于运行时间加上等待时间)
3.算法的程序实现
以下为算法的核心代码,完整的程序间附件。
3.1先来先服务
voidFIFS(intnum)//先来先服务算法计算
{
inti,j;
for(i=0;i{
if(i==0)//第一个进程
{
proc[i].RunTime=proc[i].NeedTime;
proc[i].EndTime=proc[i].StartTime+proc[i].RunTime;
}
else
{
if(proc[i].StartTime>proc[i-1].EndTime)//如果当前有作业在执行
{
proc[i].RunTime=proc[i].NeedTime;
proc[i].EndTime=proc[i].StartTime+proc[i].RunTime;
}
else
{
proc[i].RunTime=proc[i].NeedTime+proc[i-1].EndTime-proc[i].StartTime;
proc[i].EndTime=proc[i].StartTime+proc[i].RunTime;
}
}
proc[i].DQZZ_Time=proc[i].RunTime*1.0/proc[i].NeedTime;//带权周转时间
sum_Time+=proc[i].RunTime;
sum_DQ+=proc[i].DQZZ_Time;
if(i==0)printf("%sRuning....OthersWaiting....\n\n",proc[i].Name);
else
{
printf("%sRuning....",proc[i].Name);
for(j=0;j
{
printf("%s",proc[j].Name);
}
printf("isFinished....\n\n");
}
}
}
运行结果:
3.2短作业优先
voidSFS(intnum)//短作业优先
{
inti,j;
chartemp[4];
for(i=0;i{
for(j=0;j{
if(proc[j].NeedTime>proc[j+1].NeedTime)
{
proc[j].NeedTime+=proc[j+1].NeedTime;
proc[j+1].NeedTime=proc[j].NeedTime-proc[j+1].NeedTime;
proc[j].NeedTime-=proc[j+1].NeedTime;
strcpy(temp,proc[i].Name);
strcpy(proc[i].Name,proc[i+1].Name);
strcpy(proc[i+1].Name,temp);
}
}
}
for(i=0;i{
if(i==0)proc[i].RunTime=proc[i].NeedTime;
elseproc[i].RunTime=proc[i].NeedTime+proc[i-1].EndTime;
proc[i].EndTime=proc[i].StartTime+proc[i].RunTime;
proc[i].DQZZTime=proc[i].RunTime*1.0/proc[i].NeedTime;
sum_Time+=proc[i].RunTime;
sum_DQ+=proc[i].DQZZTime;
if(i==0)printf("%sRuning....OthersWaiting....\n\n",proc[i].Name);
else
{
printf("%sRuning....",proc[i].Name);
for(j=0;j
{
printf("%s",proc[j].Name);
}
printf("isFinished....\n\n");
}
}
3.3时间片轮换调度算法
/*轮转法创建进程PCB*/
voidcreate2(charalg)
{
PCB*p;
inti,time;
charna[10];
ready=NULL;
finish=NULL;
run=NULL;
printf("Enternameandtimeofroundprocess\n");
for(i=1;i<=N;i++)
{
p=malloc(sizeof(PCB));
scanf("%s",na);
scanf("%d",&time);
strcpy(p->name,na);
p->cputime=0;
p->needtime=time;
p->count=0;/*计数器*/
p->state='w';
p->round=2;/*时间片*/
if(ready!
=NULL)
insert2(p);
else
{
p->next=ready;
ready=p;
tail=p;
}
}
printf("outputofround\n");
printf("************************************************\n");
prt(alg);/*输出进程PCB信息*/
run=ready;/*将就绪队列的第一个进程投入运行*/
ready=ready->next;
run->state='R';
}
/*时间片轮转法*/
roundrun(charalg)
{
while(run!
=NULL)
{
run->cputime=run->cputime+1;
run->needtime=run->needtime-1;
run->count=run->count+1;
if(run->needtime==0)/*运行完将其变为完成态,插入完成队列*/
{
run->next=finish;
finish=run;
run->state='F';
run=NULL;
if(ready!
=NULL)
firstin();/*就绪对列不空,将第一个进程投入运行*/
}
else
if(run->count==run->round)/*如果时间片到*/
{
run->count=0;/*计数器置0*/
if(ready!
=NULL)/*如就绪队列不空*/
{
run->state='W';/*将进程插入到就绪队列中等待轮转*/
insert2(run);
firstin();/*将就绪对列的第一个进程投入运行*/
}
}
prt(alg);/*输出进程信息*/
}
}
运行结果:
4先来先服务和短作业优先算法的利弊分析
先来先服务算法的特点
(1)优点
能够体现公平性。
(2)缺点
一旦一个较长的作业进入系统后就会长时间的占用系统的资源,这样如果有优先级较高的短作业需要执行的话需要等待很长的时间。
短作业优先算法的特点
(1)优点
比FCFS改善平均周转时间和平均带权周转时间,缩短作业的等待时间,提高系统的吞吐量。
(2)缺点
对长作业非常不利,可能长时间得不到执行,未能依据作业的紧迫程度来划分执行的优先级,难以准确估计作业(进程)的执行时间,从而影响调度性能。
结束语
操作系统的作业调度是操作系统中很核心的一个问题,采用良好的算法来实现作业的调度能够提高系统各种资源的利用率。
针对不同的情况采用不同的调度算法,针对各个调度算法的利弊来合理的应用,达到最好的效果。
参考文献
【1】左万利,周长林,彭涛操作系统原理.北京:
高等教育出版社2010年7月
【2】(美)JeanAndrews,操作系统使用教程高等教育出版社2003
附录
先来先服务算法代码
#include
#include
#defineMAX100
structProc
{
charName[4];//进程名
intStartTime;//进程进入时间
intNeedTime;//进程执行时间
intRunTime;//进程周转时间
intEndTime;//进程结束时间
doubleDQZZ_Time;//带权周转时间
};
Procproc[MAX];
intsum_Time=0;
doublesum_DQ=0;
//读取数据文件
intReadFile()
{
inti=0;
FILE*fp;
fp=fopen("1.txt","r");
if(fp==NULL)
{
printf("打开文件失败!
\n");
exit(0);
}
else
{
while(!
feof(fp))
{
fscanf(fp,"%s",&proc[i].Name);
fscanf(fp,"%d",&proc[i].StartTime);
fscanf(fp,"%d",&proc[i++].NeedTime);
}
fclose(fp);
}
i--;
returni;
}
//显示原始数据
voidShow(intnum)
{
inti;
printf("进程名进入时间运行时间\n");
for(i=0;i{
printf("%6s%8d%10d\n",proc[i].Name,proc[i].StartTime,proc[i].NeedTime);
}
printf("\n");
}
//先来先服务算法计算
voidFIFS(intnum)
{
inti,j;
for(i=0;i{
//第一个进程
if(i==0)
{
proc[i].RunTime=proc[i].NeedTime;
proc[i].EndTime=proc[i].StartTime+proc[i].RunTime;
}
else
{
if(proc[i].StartTime>proc[i-1].EndTime)
{
proc[i].RunTime=proc[i].NeedTime;
proc[i].EndTime=proc[i].StartTime+proc[i].RunTime;
}
else
{
proc[i].RunTime=proc[i].NeedTime+proc[i-1].EndTime-proc[i].StartTime;
proc[i].EndTime=proc[i].StartTime+proc[i].RunTime;
}
}
proc[i].DQZZ_Time=proc[i].RunTime*1.0/proc[i].NeedTime;
sum_Time+=proc[i].RunTime;
sum_DQ+=proc[i].DQZZ_Time;
if(i==0)printf("%sRuning....OthersWaiting....\n\n",proc[i].Name);
else
{
printf("%sRuning....",proc[i].Name);
for(j=0;j
{
printf("%s",proc[j].Name);
}
printf("isFinished....\n\n");
}
}
}
//显示计算结果
voidResult(intnum)
{
inti;
printf("进程名进入时间结束时间执行时间周转时间带权周转时间\n");
for(i=0;i{
printf("%6s%8d%10d%10d%10d%12.2lf\n",proc[i].Name,proc[i].StartTime,
proc[i].EndTime,proc[i].NeedTime,proc[i].RunTime,proc[i].DQZZ_Time);
}
printf("平均周转时间为:
%.2lf\n",sum_Time*1.0/num);
printf("平均带权周转时间为:
%.2lf\n",sum_DQ*1.0/num);
printf("\n");
}
intmain()
{
intnum;
num=ReadFile();//记录进程个数
Show(num);
FIFS(num);
printf("先来先服务算法得到的结果如下:
\n\n");
Result(num);
system("pause");
return0;
}
短作业优先调度算法代码
#include
#include
#include
#defineMAX100
structProc
{
charName[4];//进程名
intStartTime;//进程进入时间
intNeedTime;//进程执行时间
intRunTime;//进程周转时间
intEndTime;//进程结束时间
doubleDQZZTime;//带全周转时间
};
Procproc[MAX];
intsum_Time=0;
doublesum_DQ=0;
//读取数据文件
intReadFile()
{
inti=0;
FILE*fp;
fp=fopen("1.txt","r");
if(fp==NULL)
{
printf("打开文件失败!
\n");
exit(0);
}
else
{
while(!
feof(fp))
{
fscanf(fp,"%s",&proc[i].Name);
fscanf(fp,"%d",&proc[i].StartTime);
fscanf(fp,"%d",&proc[i++].NeedTime);
}
fclose(fp);
}
i--;
returni;
}
//显示原始数据
voidShow(intnum)
{
inti;
printf("进程名进入时间运行时间\n");
for(i=0;i{
printf("%6s%8d%10d\n",proc[i].Name,proc[i].StartTime,proc[i].NeedTime);
}
printf("\n");
}
//短作业优先
voidSFS(intnum)
{
inti,j;
chartemp[4];
//冒泡排序
for(i=0;i{
for(j=0;j{
if(proc[j].NeedTime>proc[j+1].NeedTime)
{
proc[j].NeedTime+=proc[j+1].NeedTime;
proc[j+1].NeedTime=proc[j].NeedTime-proc[j+1].NeedTime;
proc[j].NeedTime-=proc[j+1].NeedTime;
strcpy(temp,proc[i].Name);
strcpy(proc[i].Name,proc[i+1].Name);
strcpy(proc[i+1].Name,temp);
}
}
}
//计算
for(i=0;i{
if(i==0)proc[i].RunTime=proc[i].NeedTime;
elseproc[i].RunTime=proc[i].NeedTime+proc[i-1].EndTime;
proc[i].EndTime=proc[i].StartTime+proc[i].RunTime;
proc[i].DQZZTime=proc[i].RunTime*1.0/proc[i].NeedTime;
sum_Time+=proc[i].