1、实验二 作业调度实验一. 目的要求: 用高级语言编写和调试一个或多个作业调度的模拟程序,以加深对作业调度算法的理解。 二. 例题:为单道批处理系统设计一个作业调度程序。 由于在单道批处理系统中,作业一投入运行,它就占有计算机的一切资源直到作业完成为止,因此调度作业时不必考虑它所需要的资源是否得到满足,它所占用的 CPU 时限等因素。 作业调度算法:采用先来先服务(FCFS)调度算法,即按作业提交的先后次序进行调度。总是首先调度在系统中等待时间最长的作业。 每个作业由一个作业控制块 JCB 表示,JCB 可以包含如下信息:作业名、提交时间、所需的运行时间、所需的资源、作业状态、链指针等等。 作业
2、的状态可以是等待 W(Wait)、运行 R(Run)和完成 F(Finish)三种状态之一。每个作业的最初状态总是等待 W。 各个等待的作业按照提交时刻的先后次序排队,总是首先调度等待队列中队首的作业。 每个作业完成后要打印该作业的开始运行时刻、完成时刻、周转时间和带权周转时间,这一组作业完成后要计算并打印这组作业的平均周转时间、带权平均周转时间。 调度算法的流程图如下图所示。三 . 实习题: 1、编写并调试一个单道处理系统的作业等待模拟程序。 作业等待算法:分别采用先来先服务(FCFS),最短作业优先(SJF)、响应比高者优先(HRN)的调度算法。 对每种调度算法都要求打印每个作业开始运行时
3、刻、完成时刻、周转时间、带权周转时间,以及这组作业的平均周转时间及带权平均周转时间,以比较各种算法的优缺点。源代码:#include “stdio.h“#include #include #define getpch(type) (type*)malloc(sizeof(type)struct workZtmefloat run; /作业运行时刻float end; /作业完成时刻float Zt; /周转时间float Wi; /带权周转时间;struct jcb /*定义作业控制块 JCB */char name10; /作业名float subZtme; /作业提交时间float run
4、Ztme; /作业所需的运行时间/char resource; 所需资源float Rp; /后备作业响应比char state; /作业状态struct workZtme wt;struct jcb* link; /链指针*jcb_ready=NULL,*j;typedef struct jcb JCB;float T=0;void sort() /* 建立对作业进行提交时间排列函数*/JCB *first, *second;int insert=0;if(jcb_ready=NULL)|(j-subZtme)subZtme) /*作业提交时间最短的,插入队首*/j-link=jcb_rea
5、dy;jcb_ready=j;T=j-subZtme;j-Rp=1;else /* 作业比较提交时间,插入适当的位置中*/first=jcb_ready;second=first-link;while(second!=NULL)if(j-subZtme)subZtme) /*若插入作业比当前作业提交时间短,*/*插入到当前作业前面*/j-link=second;first-link=j;second=NULL;insert=1;else /* 插入作业优先数最低,则插入到队尾*/first=first-link;second=second-link;if (insert=0) first-li
6、nk=j;void SJFget()/* 获取队列中的最短作业 */JCB *front,*minZtme,*rear;int ipmove=0;minZtme=jcb_ready;rear=minZtme-link;while(rear!=NULL)if (rear!=NULL)minZtme=rear;rear=rear-link;ipmove=1;elserear=rear-link;if (ipmove=1)front-link=minZtme-link;minZtme-link=jcb_ready;jcb_ready=minZtme;void HRNget()/* 获取队列中的最高响
7、应作业 */JCB *front,*minZtme,*rear;int ipmove=0;minZtme=jcb_ready;rear=minZtme-link;while(rear!=NULL)if (rear!=NULL)minZtme=rear;rear=rear-link;ipmove=1;elserear=rear-link;if (ipmove=1)front-link=minZtme-link;minZtme-link=jcb_ready;jcb_ready=minZtme;void input() /* 建立作业控制块函数*/int i,num;printf(“n 请输入作业数
8、:“);scanf(“%d“,for(i=0; iname);printf(“n 输入作业提交时刻:“);scanf(“%f“,printf(“n 输入作业运行时间:“);scanf(“%f“,printf(“n“);j-state='w'j-link=NULL;sort(); /* 调用 sort 函数*/int space()int l=0;JCB* jr=jcb_ready;while(jr!=NULL)l+;jr=jr-link;return(l);void disp(JCB* jr,int select) /*建立作业显示函数,用于显示当前作业*/if (select
9、=3) printf(“n 作业 运行时刻 完成时刻 周转时间 带权周转时间 n“);else printf(“n 作业 运行时刻 完成时刻 周转时间 带权周转时间 n“);printf(“ |%st“,jr-name);printf(“ |%.2ft “,jr-runZtme);if (select=3) printf(“ |%.2f “,jr-Rp);if (j=jr)printf(“ |%.2ft“,jr-wt.run);printf(“ |%.2f “,jr-wt.end);printf(“ |%.2f t“,jr-wt.Zt);printf(“ |%.2f“,jr-wt.Wi);pr
10、intf(“n“);int destroy() /*建立作业撤消函数(作业运行结束,撤消作业)*/printf(“n 作业 %s 已完成.n“,j-name);free(j);return(1);void check(int select) /* 建立作业查看函数 */JCB* jr;printf(“n 当前正在运行的作业是:%s“,j-name); /*显示当前运行作业*/disp(j,select);jr=jcb_ready;printf(“n 当前就绪队列状态为:n“); /*显示就绪队列状态*/while(jr!=NULL)jr-Rp=(T-jr-subZtme)/jr-runZtme
11、;disp(jr,select);jr=jr-link;destroy();void running(JCB* jr) /* 建立作业就绪函数(作业运行时间到,置就绪状态*/if (T=jr-subZtme) jr-wt.run=T;else jr-wt.run=jr-subZtme;jr-wt.end=jr-wt.run+jr-runZtme;jr-wt.Zt=jr-wt.end-jr-subZtme;jr-wt.Wi=jr-wt.Zt/jr-runZtme;T=jr-wt.end;int main() /*主函数*/int select=0,len,h=0;float sumZt=0,su
12、mWi=0;input();len=space();/input();printf(“nt1.FCFS 2.SJF 3.HRNnn 请选择作业调度算法:“);scanf(“%d“,while(len!=0)printf(“n 执行第%d 个作业 n“,h);j=jcb_ready;jcb_ready=j-link;j-link=NULL;j-state='R'running(j);sumZt+=j-wt.Zt;sumWi+=j-wt.Wi;check(select);if (select=2float needtime; /*运行时间*/float arrivetime;/*提
13、交时刻*/float storageN;/*系统资源*/struct jcb* link;*ready=NULL,*pb=NULL,*p;typedef struct jcb JCB;float Tc,Ti,Wi,T=0;/*完成时刻,周转时间,带权周转时间,时间量*/float TiSum=0,WiSum=0;/*平均周转时间,带权 a 平均周转时间*/float sourceN;int n;void input(); /*输入作业信息*/int space(); /* 返回就绪队列中作业的数目*/void FCFS(); /*先来先服务算法*/void disp(JCB *pr); /*
14、显示相应的作业*/void running(); /*运行作业组*/void destroy(); /* 撤销作业*/void input() /* 建立作业控制块函数*/int i,k,num;printf(“请输入所拥有的资源种类:“);scanf(“%d“,printf(“输入系统所拥有资源数:n“);for(i=0; iname);printf(“输入提交时间:“);scanf(“%f“,printf(“输入运行时间:“);scanf(“%f“,printf(“输入所需各种类的资源数:n“);for(k=0; kstoragek);printf(“n“);p-link=NULL;FCF
15、S();int space()int l=0;JCB* pr=ready;while(pr!=NULL)l+;pr=pr-link;return(l);void disp(JCB * pr) /*建立作业显示函数,用于显示当前作业*/int i;printf(“n%6st%6st%6st“,“作业名“,“运行时间“,“提交时刻“);for(i=0; iname,pr-needtime,pr-arrivetime);for(i=0; istoragei);printf(“n“);void destroy() /*建立作业撤消函数(作业运行结束,撤消作业)*/free(p);void check(
16、)JCB *first,*fir,*p;int flag=0,i,test=0;first=pb;while(first i=first-storagei)sourcei=sourcei-first-storagei;elsetest=1;if(test=0)p=first;first=first-link;p-link=NULL;if(ready=NULL)ready=p;elsefir=ready;while(fir-link!=NULL)fir=fir-link;fir-link=p;elseflag=1;pb=first;void FCFS()JCB *first,*second;in
17、t ins=0;if(pb=NULL)|(p-arrivetimearrivetime)p-link=pb;pb=p;elsefirst=pb;second=first-link;while(second!=NULL)if(p-arrivetimearrivetime)p-link=second;second=NULL;first-link=p;ins=1;elsefirst=first-link;second=second-link;if(ins=0)first-link=p;void running()JCB *pr;int i;printf(“正在运行的作业是:%sn“,p-name);
18、disp(p);if(ready!=NULL)printf(“就绪队列如下:n“);pr=ready;while(pr!=NULL)disp(pr);pr=pr-link;elseprintf(“就绪队列为空队列!n“);if(pb!=NULL)printf(“后备队列如下:n“);pr=pb;while(pr!=NULL)disp(pr);pr=pr-link;elseprintf(“后备队列为空队列!n“);printf(“作业%s 的开始运行时刻:%4.2fn“,p-name,T);Tc=T+p-needtime;T=Tc;Ti=Tc-p-arrivetime;Wi=Ti/(p-need
19、time);for(i=0; istoragei;printf(“完成时刻 周转时间 带权周转时间n“);printf(“ %4.2ft %4.2ft %4.2ft“,Tc,Ti,Wi);TiSum+=Ti;WiSum+=Wi;destroy();int main() /主函数int len;input();T=pb-arrivetime;check();len=space();while(len!=0)ready=p-link;p-link=NULL;running();if(pb!=NULL)if(ready=NULL)if(Tarrivetime)T=pb-arrivetime;check();len=space();printf(“n 该作业组的平均周转时间:%4.2fn“,TiSum /len);printf(“该作业组的带权平均周转时间:%4.2fn“,WiSum/len);运行结果:3、编写并调试一个多道程序系统的作业调度模拟程序。 作业调度算法:采用基于优先级的作业调度。 可以参考课本中的例子自行设计。 源代码:运行结果: