实验二 作业调度模拟程序
一、目的和要求
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. 允许用户选择输入每个作业的到达时间和所需运行时间。
二、 模拟程序的功能
1. 按照模拟数据的到达时间和所需运行时间,执行FCFS, SJF和HRRN调度算法,程序计算各作业的开始执行时间,各作业的完成时间,周转时间和带权周转时间(周转系数)。
2. 动态演示每调度一次,更新现在系统时刻,处于运行状态和等待各作业的相应信息(作业名、到达时间、所需的运行时间等)对于HRRN算法,能在每次调度时显示各作业的响应比R情况。
三、 模拟数据结果分析
1. 对同一个模拟数据各算法的平均周转时间,周转系数比较。
二、实验内容
根据指定的实验课题,完成设计、编码和调试工作,完成实验报告。
三、实验环境
可以采用TC,也可以选用Windows下的利用各种控件较为方便的VB,VC等可视化环境。也可以自主选择其他实验环境。
运算思想:1.先来先到:就是按照各个作业进入系统的自然次序来调度。2.短作业优先:对预计执行时间短的作业优先,通常后来的短作业不抢先正在执行的作业。3.响应比高者优先:CPU分配给就绪队列中响应比最高的进程,运用响应比算法计算,响应比是指作业等待时间与运行比值,响应比 =(等待时间+要求服务时间)/ 要求服务时间,即RR=(w+s)/s=1+w/s,因此响应比一定是大于1的。
源程序:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<malloc.h> 4 #define M 24 5 struct JCB{ 6 char name[M];//作业名 7 int rt;//到达时间 8 float r;//响应比 9 int ct;//需要CPU(运行)时间 10 int ft;//完成时的时间 11 int wt;//周转时间 12 float awt;//加权周转时间 13 }p[M]; 14 15 //输出函数 16 void Output(int a) 17 { 18 int i; 19 printf(" 作业名 到达系统时间 所需CPU时间 完成时间 周转时间 加权周转时间 "); 20 for(i=0;i<a;i++) 21 { 22 printf("%s ",p[i].name); 23 printf(" %d ",p[i].rt); 24 printf(" %d ",p[i].ct); 25 printf("%d ",p[i].ft); 26 printf("%d ",p[i].wt); 27 printf("%f ",p[i].awt); 28 } 29 } 30 31 //输入函数 32 int Input() 33 { 34 int i,a,b=0; 35 int init,k; 36 int j=1; 37 JCB f; 38 do{ 39 printf("请输入作业个数(2-24):"); 40 scanf("%d",&a); 41 if(a<2||a>24) 42 j=0; 43 else break; 44 }while(j=1); 45 for(i=0;i<a;i++) 46 { 47 printf("Please enter name:"); 48 scanf("%s",p[i].name); 49 printf("Please enter rt:"); 50 scanf("%d",&p[i].rt); 51 printf("Please enter ct:"); 52 scanf("%d",&p[i].ct); 53 p[i].ft=0; 54 p[i].wt=0; 55 p[i].awt=0; 56 p[i].r=0; 57 } 58 for(i=0;i<a;i++)//按到达系统时间先后排序 59 { 60 init=p[b].rt; 61 f=p[b]; 62 for(k=b;k<a;k++) 63 { 64 if(p[k].rt<init) 65 { 66 f=p[k]; 67 p[k]=p[b]; 68 p[b]=f; 69 init=p[b].rt; 70 } 71 } 72 b++; 73 } 74 Output(a);//按到达系统时间先后排序输出 75 return a; 76 } 77 78 //SJF算法选择短作业 79 int Selectwork(int t,int n){ 80 int i,l=0; 81 int temp,m,k=0; 82 JCB a[M]; 83 JCB b; 84 //寻找当前时间t到达系统还未完成的作业,用数组a[M]存储 85 for(i=1;i<n;i++) 86 { 87 if(p[i].rt<=t&&p[i].ft==0) 88 { 89 a[l]=p[i]; 90 l++; 91 k=l; 92 } 93 } 94 //寻找未完成作业中最短的作业 95 temp=a[0].ct; 96 b=a[0]; 97 for(m=0;m<k;m++) 98 { 99 if(a[m].ct<temp) 100 { 101 b=a[m]; 102 a[m]=a[0]; 103 a[0]=b; 104 temp=a[0].ct; 105 } 106 } 107 return a[0].ct;//返回最短作业的所需CPU时间 108 } 109 110 //HRRE算法选择响应比高的作业 111 int Choose(int t,int n) 112 { 113 int i,k,l=0; 114 int m=0; 115 float r,temp; 116 JCB a[M]; 117 JCB b; 118 //寻找当前时间t到达系统还未完成的作业,用数组a[M]存储 119 for(i=1;i<n;i++) 120 { 121 if(p[i].rt<=t&&p[i].ft==0) 122 { 123 a[l]=p[i]; 124 l++; 125 k=l; 126 } 127 } 128 //计算每个未完成作业的响应比 129 for(i=0;i<k;i++) 130 { 131 a[i].r=1+(float)(t-a[i].rt)/(float)a[i].ct; 132 } 133 //寻找未完成作业中响应比最高的作业 134 temp=a[0].r; 135 b=a[0]; 136 for(m=0;m<k;m++) 137 { 138 if(a[m].r>temp) 139 { 140 b=a[m]; 141 a[m]=a[0]; 142 a[0]=b; 143 temp=a[0].r; 144 } 145 } 146 return a[0].ct;//返回最高响应比的作业的所需CPU时间 147 } 148 149 void FCFS() 150 { 151 int i,j; 152 int now=0;//当前时间 153 j=Input(); 154 int sumwt=0;//周转时间总和 155 float sumawt=0;//带权周转时间总和 156 float avwt,avgwt;//avwt是平均周转时间,avgwt是平均带权周转时间 157 for(i=0;i<j;i++) 158 { 159 if(i==0) 160 { 161 now=p[i].rt; 162 p[i].ft=now+p[i].ct; 163 p[i].wt=p[i].ft-p[i].rt; 164 p[i].awt=p[i].wt/p[i].ct; 165 } 166 else 167 { 168 if(p[i-1].ft>p[i].rt) 169 { 170 now=p[i-1].ft; 171 p[i].ft=now+p[i].ct; 172 } 173 else 174 { 175 now=p[i].rt; 176 p[i].ft=now+p[i].ct; 177 } 178 p[i].wt=p[i].ft-p[i].rt; 179 p[i].awt=(float)p[i].wt/(float)p[i].ct; 180 } 181 sumwt+=p[i].wt; 182 sumawt+=p[i].awt; 183 } 184 avgwt=(float)sumwt/j; 185 avwt=sumawt/j; 186 Output(j); 187 printf("平均周转时间为:%f ",avgwt); 188 printf("平均带权周转时间为:%f ",avwt); 189 } 190 191 void SJF() 192 { 193 194 int i=0,j=0,k=0; 195 j=Input(); 196 int l,m,now;//当前时间 197 int a=0; 198 int sumwt=0;//周转时间总和 199 float sumawt=0;//带权周转时间总和 200 double avwt,avgwt;//avwt是平均周转时间,avgwt是平均带权周转时间 201 l=0; 202 int n=0; 203 for(i=0;i<j;i++) 204 { 205 if(i==0) 206 { 207 now=p[i].rt; 208 p[i].ft=p[i].rt+p[i].ct; 209 now=p[i].ft; 210 } 211 else 212 { 213 a=Selectwork(now,j); 214 //寻找最短作业的位置 215 for(m=0;m<j;m++) 216 if(p[m].ct==a&&p[m].ft==0) 217 { 218 k=m; 219 break; 220 } 221 p[k].ft=now+p[k].ct;//计算最短作业的完成时间 222 now=p[k].ft; 223 } 224 } 225 for(i=0;i<j;i++) 226 { 227 p[i].wt=p[i].ft-p[i].rt; 228 p[i].awt=(float)p[i].wt/(float)p[i].ct; 229 sumwt+=p[i].wt; 230 sumawt+=p[i].awt; 231 } 232 avgwt=(float)sumwt/j; 233 avwt=sumawt/j; 234 Output(j); 235 printf("平均周转时间为:%f ",avgwt); 236 printf("平均带权周转时间为:%f ",avwt); 237 238 } 239 240 void HRRN() 241 { 242 int i=0,j=0,k=0; 243 int b=0,now=0,m; 244 float sumwt=0;//周转时间总和 245 float sumawt=0;//带权周转时间总和 246 double avwt,avgwt;//avwt是平均周转时间,avgwt是平均带权周转时间 247 j=Input(); 248 for(i=0;i<j;i++) 249 { 250 if(i==0) 251 { 252 p[i].ft=p[i].rt+p[i].ct; 253 now=p[i].ft; 254 } 255 else 256 { 257 b=Choose(now,j); 258 //寻找最高响应比的作业的位置 259 for(m=0;m<j;m++) 260 if(p[m].ct==b&&p[m].ft==0) 261 { 262 k=m; 263 break; 264 } 265 p[k].ft=now+p[k].ct;//计算最高响应比的作业的完成时间 266 now=p[k].ft; 267 } 268 } 269 for(i=0;i<j;i++) 270 { 271 p[i].wt=p[i].ft-p[i].rt; 272 p[i].awt=(float)p[i].wt/(float)p[i].ct; 273 sumwt+=p[i].wt; 274 sumawt+=p[i].awt; 275 } 276 avgwt=(float)sumwt/j; 277 avwt=sumawt/j; 278 Output(j); 279 printf("平均周转时间为:%f ",avgwt); 280 printf("平均带权周转时间为:%f ",avwt); 281 } 282 283 void Start() 284 { 285 int d; 286 int j=1; 287 do{ 288 printf("1.FCFS 2.SJF 3.HRRN 请输入你需要的调度算法的序号: "); 289 scanf("%d",&d); 290 if(d<1||d>3) 291 j=0; 292 else break; 293 }while(j=1); 294 switch(d) 295 { 296 case 1: 297 FCFS(); 298 break; 299 case 2: 300 SJF(); 301 break; 302 case 3: 303 HRRN(); 304 break; 305 } 306 } 307 308 int main() 309 { 310 int i=1; 311 char a; 312 do{ 313 Start(); 314 printf("Do you want to continue?(y or n):"); 315 scanf(" %c",&a); 316 if(a=='n') 317 break; 318 }while(i=1); 319 printf("The end! "); 320 return 0; 321 }
实验总结:先来先到的算法还是比其他两个相比简单,就是需要相互赋值排列。短作业的算法就是等作业输入系统后,估算哪个长哪个短,然后安排哪个优先。但是响应比优先算法我不是很熟练。所以查了资料,才大概了解。