操作系统作业调度实验.docx
《操作系统作业调度实验.docx》由会员分享,可在线阅读,更多相关《操作系统作业调度实验.docx(32页珍藏版)》请在冰豆网上搜索。
![操作系统作业调度实验.docx](https://file1.bdocx.com/fileroot1/2023-2/1/dfa9f626-38a4-43ef-87ab-04c149adeb93/dfa9f626-38a4-43ef-87ab-04c149adeb931.gif)
操作系统作业调度实验
实验二作业调度
一、实验题目:
1、单道批处理系统的作业调度模拟程序。
2、编写采用先来先服务算法多道批处理系统的作业调度模拟程序。
二、实验目的:
通过对单道批处理系统的作业调度和采用先来先服务算法多道批处理系统作业调度的模拟,进一步理解作业调度的过程,加深对单道和多道的作业运行状态和作业调度过程、调度算法的理解。
三、实验设备及环境:
1、硬件设备:
PC机一台
2、软件环境:
安装Windows操作系统或者Linux操作系统,并安装相关的程序开发环境,如C\C++\Java等编程语言环境。
四、实验内容及要求:
1、单道批处理系统作业调度
(1)由于在单道批处理系统中,作业一旦投入运行,它就占有计算机的一切资源直到作业完成为止,因此调度作业时不必考虑它所需要的资源是否得到满足,它所占用的CPU时限等因素。
(2)每个作业由一个作业控制块JCB表示,JCB可以包含如下信息:
作业名name、作业大小size、所需的运行时间ntime、作业已运行时间rtime、所需的资源machine、作业状态state等。
作业指针link,用来将JCB表排成队列。
作业的状态可以是等待W(Wait)、运行R(Run)和完成F(Finish)三种状态之一。
每个作业的最初状态总是等待W状态。
(3)对每种调度算法都要求显示每个作业开始运行时刻、完成时刻、周转时间、带权周转时间,以及这组作业的平均周转时间及带权平均周转时间。
2、采用先来先服务算法多道批处理系统的作业调度
(1)采用多道程序设计方法的操作系统,在系统中要经常保留多个运行的作业,以提高系统效率。
作业调度从系统已接纳的暂存在输入井中的一批作业中挑选出若干个可运行的作业,并为这些被选中的作业分配所需的系统资源。
对被选中运行的作业必须按照它们各自的作业说明书规定的步骤进行控制。
(2)批处理作业调度程序负责从输入井中选择若干个作业进入主存,为它们分配必要的资源,当它们能够被进程调度选中时,就可占用处理器运行。
作业调度选择一个作业的必要条件是系统中现有的尚未分配的资源可满足该作业的资源要求。
但有时系统中现有的尚未分配的资源既可满足某个作业的要求也可满足其它一些作业的要求,那么,作业调度必须按一定的算法在这些作业中做出选择。
先来先服务算法是按照作业进入输入井的先后次序来挑选作业,先进入输入井的作业优先被挑选,当系统中现有的尚未分配的资源不能满足先进入输入井的作业时,那么顺序挑选后面的作业。
(3)假定某系统可供用户使用的主存空间共100K,并有5台磁带机。
(4)多道批处理系统中JCB表示同单道批处理系统相同。
3、为了清楚地观察每个进程的调度过程,程序应将每个时间片内的进程的情况显示出来,包括正在运行的进程,处于就绪队列中的进程和处于阻塞队列中的进程。
4、分析程序运行的结果,谈一下自己的认识。
五、实现程序流程图及源代码
1、算法流程图
(1)单道批处理系统中作业调度按:
先来先服务算法实现流程;最短作业优先算法;高响应比算法流程图:
(2)采用先来先服务算法多道批处理系统的作业流程图
2、主要的常量变量
(1)单道批处理系统作业调度常量、变量
intn;
floatT1=0,T2=0;
inttimes=0;
structjcb//作业控制块
{
charname[10];//作业名
intreachtime;//作业到达时间
intstarttime;//作业开始时间
intneedtime;//作业需要运行的时间
floatsuper;//作业的响应比
intfinishtime;//作业完成时间
floatcycletime;//作业周转时间
floatcltime;//作业带权周转时间
charstate;//作业状态
structjcb*next;//结构体指针
}*ready=NULL,*p,*q;
typedefstructjcbJCB;
(2)多道批处理系统作业调度常量、变量
#definegetpch(type)(type*)malloc(sizeof(type))//宏定义变量type
#definearea100//宏定义内存空间总大小
#definesummachine5//宏定义内存磁带数总数
#defineNULL0
structpcb//定义结构体pcb
{
intjobs;//进入计算机作业总数
intjobnum;//进入内存作业数量
intwellnum;//输入井中的作业个数
charname[10];//作业名
charstate;//作业状态
intsize;//作业大小
intmachine;//某个作业所占用的磁带机总数
intntime;//作业需要运行的总时间
intrtime;//作业已经运行的时间
structpcb*link;//自定义结构体指针link
}*ready=NULL,*p,*q,num;//自定义结构体指针变量ready,p,并将ready设为空指针
typedefstructpcbPCB;//定义作业控制块PCB
3、主要模块
(1)单道批处理系统作业调度模块
voidinize()//初始化界面
voidinital()//建立作业控制块队列,先将其排成先来先服务的模式队列
voiddisp(JCB*q,intm)//显示作业运行后的周转时间及带权周转时间等
voidrunning(JCB*p,intm)//运行作业
voidsuper()//计算队列中作业的高响应比
voidfinal()//最后打印作业的平均周转时间,平均带权周转时间
voidhrn(intm)//高响应比算法
voidsjf(intm)//最短作业优先算法
voidfcfs(intm)//先来先服务算法
(2)多道批处理系统作业调度模块
voidinize()//初始化界面函数
voidwell()//对进入计算机的所有作业按从大到小的顺序排队
voidsort()//内存中运行完一次的作业插到队尾
voidinput()//输入要运行的各个作业的基本信息
voiddisp()//建立显示正在运行的作业的运行情况的函数
voiddisp2(PCB*pr)//建立显示内存就绪队列中所有作业的函数
voiddisp3(PCB*r)//建立显示输入井中作业情况的函数
voidcheck()//建立作业查看函数
voiddestroy()//建立作业撤销函数(对运行完的作业进行撤销)
voidchoose1()//建立从输入井中选择满足条件的作业的函数
voidchoose2()//建立再次从输入井中挑选满足条件的作业的函数
voidrunning()
voidduodao()
voidmenu()//菜单
voidmain()//主函数
4、代码
(1)单道批处理系统作业调度实现源代码
/*****************************************************************
*文件名:
Simple_Batch_Systems.c
*功能:
单道批处理系统的作业调度模拟程序
*******************************************************************/
#include
#include
#include
#definegetpch(type)(type*)malloc(sizeof(type))
intn;
floatT1=0,T2=0;
inttimes=0;
structjcb//作业控制块
{
charname[10];//作业名
intreachtime;//作业到达时间
intstarttime;//作业开始时间
intneedtime;//作业需要运行的时间
floatsuper;//作业的响应比
intfinishtime;//作业完成时间
floatcycletime;//作业周转时间
floatcltime;//作业带权周转时间
charstate;//作业状态
structjcb*next;//结构体指针
}*ready=NULL,*p,*q;
typedefstructjcbJCB;
//------------------------------------------------------------------------------------------------
voidinize()//初始化界面
{
printf("\n\n\t\t********************************************\t\t\n");
printf("\t\t\t\t实验二作业调度\n");
printf("\t\t*********************************************\t\t\n");
printf("\n\n\n\t\t\t计算机系802班\n");
printf("\t\t\t姓名:
李雪娇\n");
printf("\t\t\t学号:
08030043\n");
printf("\t\t\t完成时间:
2010年12月15日\n\n\n\n");
printf("\t\t\t\t\t请输入任意键进入演示过程\n");
getch();
}
//------------------------------------------------------------------------------------------------
voidinital()//建立作业控制块队列,先将其排成先来先服务的模式队列
{
inti;//定义整型变量i
printf("\n输入作业数:
");//输入要输入的作业数
scanf("%d",&n);
for(i=0;i{
p=getpch(JCB);
printf("\n输入作业名:
");//输入作业名
scanf("%s",p->name);
getch();
p->reachtime=i;
printf("作业默认到达时间:
%d",i);//以作业的到达顺序作为作业默认到达时间
printf("\n输入作业要运行的时间:
");//作业运行所需时间
scanf("%d",&p->needtime);
p->state='W';//将作业状态置为等待
p->next=NULL;//尾指针置空
if(ready==NULL)ready=q=p;//如果就绪队列为空,将头指针指向p
else{//如果就绪队列不为空,将输入的作业插入到队尾
q->next=p;
q=p;
}
}
}
//------------------------------------------------------------------------------------------------
voiddisp(JCB*q,intm)//显示作业运行后的周转时间及带权周转时间等
{
if(m==3)//显示高响应比算法调度作业后的运行情况
{
printf("\n作业%s正在运行,估计其运行情况:
\n",q->name);
printf("开始运行时刻:
%d\n",q->starttime);
printf("完成时刻:
%d\n",q->finishtime);
printf("周转时间:
%f\n",q->cycletime);
printf("带权周转时间:
%f\n",q->cltime);
printf("相应比:
%f\n",q->super);
getch();
}
else//显示先来先服务,最短作业优先算法调度后作业的运行情况
{
printf("\n作业%s正在运行,估计其运行情况:
\n",q->name);
printf("开始运行时刻:
%d\n",q->starttime);
printf("完成时刻:
%d\n",q->finishtime);
printf("周转时间:
%f\n",q->cycletime);
printf("带权周转时间:
%f\n",q->cltime);
getch();
}
}
//------------------------------------------------------------------------------------------------
voidrunning(JCB*p,intm)//运行作业
{
if(p==ready)//先将要运行的作业从队列中分离出来
{
ready=p->next;//将ready指针后移
p->next=NULL;//将要运行的作业的链置空
}
else
{
q=ready;
while(q->next!
=p)q=q->next;
q->next=p->next;
}
p->starttime=times;//计算作业运行后的完成时间,周转时间等等
p->state='R';//将状态置为'运行'
p->finishtime=p->starttime+p->needtime;//完成时间=作业开始时间+作业需要运行时间
p->cycletime=(float)(p->finishtime-p->reachtime);//周转时间=完成时间-到达时间
p->cltime=(float)(p->cycletime/p->needtime);//带权周转时间=周转时间/需要运行时间
T1+=p->cycletime;
T2+=p->cltime;
disp(p,m);//调用disp()函数,显示作业运行情况
times+=p->needtime;//更新当前时间
p->state='F';//将状态置为'完成'
printf("\n%shasbeenfinished!
\npressanykeytocontinue...\n",p->name);
free(p);//释放运行后的作业
getch();
}
//------------------------------------------------------------------------------------------------
voidsuper()//计算队列中作业的高响应比
{
JCB*padv;
padv=ready;
do{
if(padv->state=='W'&&padv->reachtime<=times)
padv->super=(float)(times-padv->reachtime+padv->needtime)/padv->needtime;
padv=padv->next;
}while(padv!
=NULL);
}
//------------------------------------------------------------------------------------------------
voidfinal()//最后打印作业的平均周转时间,平均带权周转时间
{
floats,t;
t=T1/n;//计算平均周转时间
s=T2/n;//计算平均带权周转时间
getch();
printf("\n\n作业已经全部完成!
");
printf("\n%d个作业的平均周转时间是:
%f",n,t);
printf("\n%d个作业的平均带权周转时间是%f:
\n\n\n",n,s);
}
//------------------------------------------------------------------------------------------------
voidhrn(intm)//高响应比算法
{
JCB*min;
inti,iden;//定义正型变量i,iden
system("cls");
inital();//调用inital()函数
for(i=0;i{
p=min=ready;iden=1;
super();//调用super()函数,计算队列中作业的高响应比
do{
if(p->state=='W'&&p->reachtime<=times)//作业的状态为等待,且到达时间比当前时间早
if(iden)
{
min=p;iden=0;
}
elseif(p->super>min->super)min=p;
p=p->next;//p指针后移
}while(p!
=NULL);
if(iden)
{
i--;times++;//printf("\ntime=%d:
\tnoJCBsubmib...wait...",time);
if(times>1000){printf("\nruntimeistoolong...error...");getch();}
}
else
{
running(min,m);//调用running()函数
}
}//for
final();//调用running()函数
}
//------------------------------------------------------------------------------------------------
voidsjf(intm)//最短作业优先算法
{
JCB*min;//定义指针变量min,指向最短作业
inti,iden;//定义整形变量i,iden
system("cls");//调用系统函数清屏
inital();//调用inital()函数
for(i=0;i{
p=min=ready;iden=1;//将p,min指针指向就绪队列第一个作业,给标志变量赋值
do{
if(p->state=='W'&&p->reachtime<=times)//如果作业状态为等待,且到达时间在现在时间之前
if(iden){
min=p;iden=0;//iden等于一时,将min指向p所指作业,把0赋给iden
}
elseif(p->needtimeneedtime)min=p;//当前作业需要时间小于最小需要时间时,将min指向p所指作业
p=p->next;//指针后移
}while(p!
=NULL);//执行上述语句,到p为空时跳出循环
if(iden){
i--;//printf("\ntime=%d:
\tnoJCBsubmib...wait...",time);
times++;
if(times>100){printf("\nruntimeistoolong...error");getch();}
}
else{
running(min,m);//调用running()函数
}
}
final();//调用running()函数
}
//------------------------------------------------------------------------------------------------
voidfcfs(intm)//先来先服务算法
{
inti,iden;//定义整形变量i,iden
system("cls");//调用系统函数清屏
inital();//调用inital()函数,建立作业控制块队列
for(i=0;i{
p=ready;iden=1;//将p指针指向队首作业,给iden赋1
do{
if(p->state=='W'&&p->reachtime<=times)iden=0;//p作业状态为'w'且到达时间在
//当前时间之前,给iden赋0,跳出循环
if(iden)p=p->next;
}while(p!
=NULL&&iden);//运行满足条件的作业
if(iden)//没有满足条件的作业时,输出提示信息,当前时间加1
{
i--;
printf("\n没有满足要求的进程,需等待");
times++;
if(times>100){printf("\n时间过长");getch();}//时间过长提示
}
else
{
running(p,m);//调用running()函数
}
}
final();//调用final()函数
}
//------------------------------------------------------------------------------------------------
voidmune()//主菜单
{
intm;
system("cls");
printf("\n\n\t\t*********************************************\t\t\n");
printf("\t\t\t\t作业调度演示\n");
printf("\t\t*********************************************\t\t\n");
printf("\n\n\n\t\t\t1.先来先服务算法.");
printf("\n\t\t\t2.最短作业优先算法.");
printf("\n\t\t\t3.响应比高者优先算法");
printf("\n\t\t\t0.退出程序.");
printf("\n\n\t\t\t\t选择所要操作:
");
scanf("%d",&m);
switch(m)
{
case1:
fcfs(m);//先来先服务算法
getch();
system("cls");//清屏
times=0;//完成一次作业输入时,重置当前时间
mune();//调用函数自身
break;
case2:
sjf(m);//最短作业优先算法
getch();
system("cls");