操作系统作业调度实验.docx
《操作系统作业调度实验.docx》由会员分享,可在线阅读,更多相关《操作系统作业调度实验.docx(12页珍藏版)》请在冰豆网上搜索。
操作系统作业调度实验
实验二作业调度
一、实验名称
作业调度算法的模拟实现
二、实验目标
作业调度又称宏观调度,其主要任务是对磁盘设备上大量的后备作业,以一定的原则进行挑选,给选中的作业分配内存等必须的资源,建立其相应的进程,让其投入运行。
本实验要求学生用高级程序设计语言编写和调试一个简化的作业调度程序,模拟实现的调度算法包括:
先来先服务调度算法,短作业优先调度算法,响应比高者优先调度算法等,并对这些算法的性能做比较和评价。
以加深学生对作业、作业调度以及作业调度的各种算法的理解。
三、实验环境要求
Windows+VisualC++6.0;
四、实验基本原理
作业调度主要是完成作业从后备状态到执行状态的转变,以及从执行状态到完成状态的转变。
(1)创建JCB(作业控制块):
系统在作业进入后备状态时为每个作业创建一个作业控制块(JCB),从而使该作业可被调度程序感知。
当该作业执行完毕进入完成状态时候,系统自动撤销其JCB并释放有关资源,进而撤销该作业。
(2)按照作业调度算法,从后备队列中挑选一作业投入运行。
作业调度程序为运行作业建立相应的进程,并分配资源。
(3)主要的作业调度算法包括:
先来先服务(FCFS)、短作业优先和最高响应比。
(4)调度策略的指标:
最常用的调度性能指标有,周转时间(带权)、吞吐率、响应时间以及设备利用率。
五、数据结构设计
(1)作业控制块,包括作业的基本信息描述。
structtime//时间的数据结构
{
inthour;
intminute;
};
structJob//作业
{
stringjobname;//作业名
timeintime;//进入时间
intruntime;//作业估计运行时间
timestarttime;//作业开始时间
timeendtime;//作业结束时间
intcycletime;//作业周转时间
floatcltime;//作业带权周转时间
boolhaverun;//是否已运行
};
六、流程图
图1作业调度算法流程图
七、源代码
#include
#include
usingnamespacestd;
structtime//时间的数据结构
{
inthour;
intminute;
};
structJob//作业
{
stringjobname;//作业名
timeintime;//进入时间
intruntime;//作业估计运行时间
timestarttime;//作业开始时间
timeendtime;//作业结束时间
intcycletime;//作业周转时间
floatcltime;//作业带权周转时间
boolhaverun;//是否已运行
};
floatT=0;//作业平均周转时间
floatW=0;//作业带权平均周转时间
voidshowInput(Jobjob[],int&n)//输入提示
{
cout<<"**********请按作业进入时间先后顺序输入*********"<for(inti=0;i{
cout<<"作业"<
"<cout<<"作业名:
";
cin>>job[i].jobname;
cout<<"作业进入时间:
";
scanf("%d:
%d",&job[i].intime.hour,&job[i].intime.minute);
cout<<"作业估计运行时间:
";
cin>>job[i].runtime;
job[i].starttime.hour=0;
job[i].starttime.minute=0;
job[i].endtime.hour=0;
job[i].endtime.minute=0;
job[i].cycletime=0;
job[i].cltime=0;
job[i].haverun=false;//标记为未运行
cout<<"*********************"<}
}
voidInit(Jobjob[],int&n)//初始化
{
for(inti=0;i{
job[i].starttime.hour=0;
job[i].starttime.minute=0;
job[i].endtime.hour=0;
job[i].endtime.minute=0;
job[i].cycletime=0;
job[i].cltime=0;
job[i].haverun=false;//标记为未运行
}
T=0;
W=0;
}
voidshowTime(timetime)//显示时间
{
cout<"<}
inttimeDiff(timet1,timet2)//计算时间差,时间t1比t2大
{
returnt1.hour*60+t1.minute-(t2.hour*60+t2.minute);
}
timetimeAdd(timetime,intaddtime)//时间相加
{
time.hour+=addtime/60;
time.minute+=addtime%60;
if(time.minute>=60)
{
time.hour++;
time.minute-=60;
}
returntime;
}
boolcomtime(timet1,timet2)//比较两个时间的大小,第一个大就返回TRUE
{
if(t1.hour>t2.hour)
returntrue;
elseif(t1.hour==t2.hour&&t1.minute>=t2.minute)
returntrue;
else
returnfalse;
}
voidshowResult(Jobjob[],int&n)//显示结果
{
cout<<"jobname\tintime\truntime\tsttime\tendtime\t周转时间(分钟)\t带权周转时间"<cout<<"*******************************************************************"<for(inti=0;i{
cout<showTime(job[i].intime);
cout<<"\t"<showTime(job[i].starttime);
cout<<"\t";
showTime(job[i].endtime);
cout<<"\t"<}
cout<<"作业平均周转时间:
T="<cout<<"作业带权平均周转时间:
W="<}
intminRuntime(Jobjob[],int&n,time&t)//找出作业中最短作业下标
{
intmin=-1;
for(inti=0;i{
if(job[i].haverun==false&&comtime(t,job[i].intime)==true)
{
min=i;
break;
}
}
for(intj=min+1;jif(job[j].haverun==false&&job[j].runtimemin=j;
returnmin;
}
voidSJF(Jobjob[],int&n)//短作业优先作业调度
{
structtimet;
job[0].starttime.hour=job[0].intime.hour;
job[0].starttime.minute=job[0].intime.minute;
job[0].endtime=timeAdd(job[0].starttime,job[0].runtime);
job[0].haverun=true;
job[0].cycletime=timeDiff(job[0].endtime,job[0].intime);
job[0].cltime=job[0].cycletime*1.0/job[0].runtime;
T+=job[0].cycletime;
W+=job[0].cltime;
t=job[0].endtime;
while(minRuntime(job,n,t)!
=-1)
{
inti=minRuntime(job,n,t);
if(comtime(job[i].intime,t))
job[i].starttime=job[i].intime;
else
job[i].starttime=t;
job[i].endtime=timeAdd(job[i].starttime,job[i].runtime);
job[i].haverun=true;
job[i].cycletime=timeDiff(job[i].endtime,job[i].intime);
job[i].cltime=job[i].cycletime*1.0/job[i].runtime;
T+=job[i].cycletime;
W+=job[i].cltime;
t=job[i].endtime;
}
}
intFirstintime(Jobjob[],int&n)//找出作业中最先到的
{
intmin=-1;
for(inti=0;i{
if(job[i].haverun==false)
{
min=i;
break;
}
}
for(intj=min+1;jif(job[j].haverun==false&&comtime(job[min].intime,job[j].intime))
min=j;
returnmin;
}
voidFCFS(Jobjob[],int&n)//先来先服务作业调度
{
structtimet;
job[0].starttime.hour=job[0].intime.hour;
job[0].starttime.minute=job[0].intime.minute;
job[0].endtime=timeAdd(job[0].starttime,job[0].runtime);
job[0].haverun=true;
job[0].cycletime=timeDiff(job[0].endtime,job[0].intime);
job[0].cltime=job[0].cycletime*1.0/job[0].runtime;
T+=job[0].cycletime;
W+=job[0].cltime;
t=job[0].endtime;
while(Firstintime(job,n)!
=-1)
{
inti=Firstintime(job,n);
if(comtime(job[i].intime,t))
job[i].starttime=job[i].intime;
else
job[i].starttime=t;
job[i].endtime=timeAdd(job[i].starttime,job[i].runtime);
job[i].haverun=true;
job[i].cycletime=timeDiff(job[i].endtime,job[i].intime);
job[i].cltime=job[i].cycletime*1.0/job[i].runtime;
T+=job[i].cycletime;
W+=job[i].cltime;
t=job[i].endtime;
}
}
voidmain()
{
cout<<"请输入作业数:
";
intn;//作业数
cin>>n;
Job*job=newJob[n];
if(n<=0)
{
cout<<"输入不合法!
";
exit(-1);
}
else
{
showInput(job,n);
cout<FCFS(job,n);
cout<<"先来先服务:
"<showResult(job,n);
cout<Init(job,n);
SJF(job,n);//短作业优先
cout<<"短作业优先:
"<showResult(job,n);
}
system("pause");
}
八、运行结果
用户输入作业的相关信息,程序输出相应的各种算法运行结果。
以下为程序运行后的输出数据:
输入信息:
运行结果:
九、结果分析
(1)先来先服务输出数据分析:
作业1至作业4的提交时间分别为 8:
00、8:
50、9:
00、9:
50。
所以作业的执行序列为作业1、作业2、作业3和作业4。
前一个作业的完成时间即为后一个作业的开始时间。
(2)短作业优先输出数据分析:
作业1至作业4的提交时间分别为 8:
00、8:
50、9:
00、9:
50。
系统时间
时间8:
00 :
作业1提交,马上被调度运行,开始时间为8:
00,运行时间为2:
00。
时间8:
50 :
作业2提交,因作业1在运行,故作业2暂时等待。
时间9:
00 :
作业3提交,因作业1在运行,故作业3暂时等待。
时间9:
50 :
作业4提交,因作业1在运行,故作业4暂时等待。
时间10:
00 :
作业1完成,进入完成队列。
目前提交的作业有:
作业2、作业3、作业4;按短作业优先原则,作业3运行时间为0:
10最短,故作业3被调度运行。
作业2和作业4继续等待。
时间10:
10 :
作业3完成,进入完成队列。
目前提交的作业有:
作业2和作业4。
按短作业优先原则,作业4的运行时间为0:
20最短,故作业4被调度运行,作业2继续等待。
时间10:
30 :
作业4完成,进入完成队列。
目前提交的作业仅有作业2,故作业2被调度运行,运行时间为0:
5。
时间11:
20 :
作业2完成,进入完成队列。
程序执行完毕。
十、本次实验体会
加深了对作业的理解,掌握了基本的作业调度算法。
通过对各种作业调度算法的综合比较,理解各种算法的优劣。
十一、参考资料
(1)陈向群杨芙清著《操作系统教程》北京大学出版社
(2)AndrewS.Tanenbaum著陈向群马洪兵等译《现代操作系统》机械工业出版社