1111《操作系统教程》实验二 作业调度模拟程序
实验二 作业调度模拟程序
一、目的和要求
1. 实验目的
(1)加深对作业调度算法的理解;
(2)进行程序设计的训练。
2.实验要求
用高级语言编写一个或多个作业调度的模拟程序。
单道批处理系统的作业调度程序。作业一投入运行,它就占有计算机的一切资源直到作业完成为止,因此调度作业时不必考虑它所需要的资源是否得到满足,它所运行的时间等因素。
作业调度算法:
1) 采用先来先服务(FCFS)调度算法,即按作业到达的先后次序进行调度。总是首先调度在系统中等待时间最长的作业。
2) 短作业优先 (SJF) 调度算法,优先调度要求运行时间最短的作业。
3) 响应比高者优先(HRRN)调度算法,为每个作业设置一个优先权(响应比),调度之前先计算各作业的优先权,优先数高者优先调度。RP (响应比)= 作业周转时间 / 作业运行时间=1+作业等待时间/作业运行时间
每个作业由一个作业控制块JCB表示,JCB可以包含以下信息:作业名、提交(到达)时间、所需的运行时间、所需的资源、作业状态、链指针等等。
作业的状态可以是等待W(Wait)、运行R(Run)和完成F(Finish)三种之一。每个作业的最初状态都是等待W。
一、 模拟数据的生成
1. 允许用户指定作业的个数(2-24),默认值为5。
2. 允许用户选择输入每个作业的到达时间和所需运行时间。
3. (**)从文件中读入以上数据。
4. (**)也允许用户选择通过伪随机数指定每个作业的到达时间(0-30)和所需运行时间(1-8)。
二、 模拟程序的功能
1. 按照模拟数据的到达时间和所需运行时间,执行FCFS, SJF和HRRN调度算法,程序计算各作业的开始执行时间,各作业的完成时间,周转时间和带权周转时间(周转系数)。
2. 动态演示每调度一次,更新现在系统时刻,处于运行状态和等待各作业的相应信息(作业名、到达时间、所需的运行时间等)对于HRRN算法,能在每次调度时显示各作业的响应比R情况。
3. (**)允许用户在模拟过程中提交新作业。
4. (**)编写并调度一个多道程序系统的作业调度模拟程序。 只要求作业调度算法:采用基于先来先服务的调度算法。 对于多道程序系统,要假定系统中具有的各种资源及数量、调度作业时必须考虑到每个作业的资源要求。
三、 模拟数据结果分析
1. 对同一个模拟数据各算法的平均周转时间,周转系数比较。
2. (**)用曲线图或柱形图表示出以上数据,分析算法的优点和缺点。
四、 其他要求
1. 完成报告书,内容完整,规格规范。
2. 实验须检查,回答实验相关问题。
注:带**号的条目表示选做内容。
二、实验内容
根据指定的实验课题,完成设计、编码和调试工作,完成实验报告。
三、实验环境
可以采用TC,也可以选用Windows下的利用各种控件较为方便的VB,VC等可视化环境。也可以自主选择其他实验环境。
四、源代码
1 #include "stdio.h" 2 #include <stdlib.h> 3 #include <conio.h> 4 #define getpch(type) (type*)malloc(sizeof(type)) 5 #define NULL 0 6 7 int wait=0; 8 9 struct worktime{ 10 float Tb; //作业运行时刻 11 float Tc; //作业完成时刻 12 float Ti; //周转时间 13 float Wi; //带权周转时间 14 }; 15 16 struct jcb { /*定义作业控制块JCB */ 17 char name[10]; //作业名 18 float subtime; //作业提交时间 19 float runtime; //作业所需的运行时间 20 char resource; //所需资源 21 float Rp; //后备作业响应比 22 char state; //作业状态 23 struct worktime wt; 24 struct jcb* link; //链指针 25 }*jcb_ready=NULL,*j; 26 27 typedef struct jcb JCB; 28 float T=0; 29 30 void sort() /* 建立对作业进行提交时间排列函数*/ 31 { 32 JCB *first, *second; 33 int insert=0; 34 if((jcb_ready==NULL)||((j->subtime)<(jcb_ready->subtime))) /*作业提交时间最短的,插入队首*/ 35 { 36 j->link=jcb_ready; 37 jcb_ready=j; 38 T=j->subtime; 39 j->Rp=1; 40 } 41 else /* 作业比较提交时间,插入适当的位置中*/ 42 { 43 first=jcb_ready; 44 second=first->link; 45 while(second!=NULL) 46 { 47 if((j->subtime)<(second->subtime)) /*若插入作业比当前作业提交时间短,*/ 48 { /*插入到当前作业前面*/ 49 j->link=second; 50 first->link=j; 51 second=NULL; 52 insert=1; 53 } 54 else /* 插入作业优先数最低,则插入到队尾*/ 55 { 56 first=first->link; 57 second=second->link; 58 } 59 } 60 if (insert==0) first->link=j; 61 } 62 } 63 64 void SJFget()/* 获取队列中的最短作业 */ 65 { 66 JCB *front,*mintime,*rear; 67 int ipmove=0; 68 mintime=jcb_ready; 69 rear=mintime->link; 70 while(rear!=NULL) 71 72 if ((rear!=NULL)&&(T>=rear->subtime)&&(mintime->runtime)>(rear->runtime)) 73 { 74 front=mintime; 75 mintime=rear; 76 rear=rear->link; 77 ipmove=1; 78 } 79 else 80 rear=rear->link; 81 if (ipmove==1){ 82 front->link=mintime->link; 83 mintime->link=jcb_ready; 84 } 85 jcb_ready=mintime; 86 } 87 88 void HRNget()/* 获取队列中的最高响应作业 */ 89 { 90 JCB *front,*mintime,*rear; 91 int ipmove=0; 92 mintime=jcb_ready; 93 rear=mintime->link; 94 while(rear!=NULL) 95 if ((rear!=NULL)&&(T>=rear->subtime)&&(mintime->Rp)<(rear->Rp)) 96 { 97 front=mintime; 98 mintime=rear; 99 rear=rear->link; 100 ipmove=1; 101 } 102 else 103 rear=rear->link; 104 if (ipmove==1){ 105 front->link=mintime->link; 106 mintime->link=jcb_ready; 107 } 108 jcb_ready=mintime; 109 } 110 111 void input() /* 建立作业控制块函数*/ 112 { 113 int i,count; 114 printf("\n How many task do you want to work?"); 115 scanf("%d",&count); 116 for(i=0;i<count;i++) 117 { 118 printf("\n Task_No.%d:\n",i); 119 j=getpch(JCB); 120 printf("\n Input the task`name:"); 121 scanf("%s",j->name); 122 printf("\n Task`submission time:"); 123 scanf("%f",&j->subtime); 124 printf("\n Task`s running time:"); 125 scanf("%f",&j->runtime); 126 printf("\n"); 127 j->state='w'; 128 j->link=NULL; 129 sort(); /* 调用sort函数*/ 130 } 131 } 132 133 int space() 134 { 135 int l=0; JCB* jr=jcb_ready; 136 while(jr!=NULL) 137 { 138 l++; 139 jr=jr->link; 140 } 141 return(l); 142 } 143 144 void disp(JCB* jr,int select) /*建立作业显示函数,用于显示当前作业*/ 145 { 146 if (select==3) printf("\n Task Service Response Submission Finish Turnaround Wei-turnaround\n"); 147 else if(wait!=1)printf("\n Task Service Run Finish Turnaround Weighted turnaround\n"); 148 printf(" |%s ",jr->name); 149 printf(" |%.2f ",jr->runtime); 150 if (select==3) printf(" |%.2f ",jr->Rp); 151 if (j==jr){ 152 printf(" |%.2f ",jr->wt.Tb); 153 printf(" |%.2f ",jr->wt.Tc); 154 printf(" |%.2f ",jr->wt.Ti); 155 printf(" |%.2f",jr->wt.Wi); 156 } 157 printf("\n"); 158 } 159 160 int destroy() /*建立作业撤消函数(作业运行结束,撤消作业)*/ 161 { 162 printf("\n Task [%s] Done.\n",j->name); 163 free(j); 164 return(1); 165 } 166 167 void check(int select) /* 建立作业查看函数 */ 168 { 169 JCB* jr; 170 printf("\n\n ...The running task is:%s",j->name); /*显示当前运行作业*/ 171 disp(j,select); 172 jr=jcb_ready; 173 printf("\n\n ...The waiting queue:\n"); /*显示就绪队列状态*/ 174 while(jr!=NULL) 175 { 176 wait=1; 177 jr->Rp=(T-jr->subtime)/jr->runtime; 178 disp(jr,select); 179 jr=jr->link; 180 } 181 wait=0; 182 destroy(); 183 } 184 185 186 187 188 void running(JCB* jr) /* 建立作业就绪函数(作业运行时间到,置就绪状态*/ 189 { 190 if (T>=jr->subtime) jr->wt.Tb=T; else jr->wt.Tb=jr->subtime; 191 jr->wt.Tc=jr->wt.Tb+jr->runtime; 192 jr->wt.Ti=jr->wt.Tc-jr->subtime; 193 jr->wt.Wi=jr->wt.Ti/jr->runtime; 194 T=jr->wt.Tc; 195 } 196 197 int main() /*主函数*/ 198 { 199 int select=0,len,h=0; 200 float sumTi=0,sumWi=0; 201 input(); 202 len=space(); 203 printf("\n\n\t1.FCFS 2.SJF 3.HRN\n\nSelect the three of one scheduling algorithm:?"); 204 scanf("%d",&select); 205 while((len!=0)&&(jcb_ready!=NULL)) 206 { 207 h++; 208 printf("\n ...Task No%d... \n",h); 209 j=jcb_ready; 210 jcb_ready=j->link; 211 j->link=NULL; 212 j->state='R'; 213 running(j); 214 sumTi+=j->wt.Ti; 215 sumWi+=j->wt.Wi; 216 check(select); 217 if (select==2&&h<len-1) SJFget(); 218 if (select==3&&h<len-1) HRNget(); 219 printf("\n\n ...Press any key to countine...\n"); 220 getchar(); 221 getchar(); 222 } 223 printf("\n\n ...Done...\n"); 224 printf("\t ...AVG Turnaround time:%.2f...\n\n",sumTi/h); 225 printf("\t ...AVG Weighted turnaround time:%.2f...\n\n",sumWi/h); 226 getchar(); 227 }