实验二 作业调度模拟程序
一、目的和要求
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 |
一个作业具备什么信息? |
作业由三部分组成,即程序、数据和作业说明书。一个作业可以包含多个程序和多个数据集,但必须至少包含一个程序。否则将不成为作业。 |
|
3 |
为了方便模拟调度过程,作业使用什么方式的数据结构存放和表示?JCB |
由作业说明书在系统中生成一个称为作业控制块(job control block,JCB)的表格。该表格登记该作业所要求的资源情况、预计执行时间和执行优先级等。从而,操作系统通过该表了解到作业要求,并分配资源和控制作业中程序和数据的编译、链接、装入和执行等。 |
|
4 |
操作系统中,常用的作业调度算法有哪些? |
先来先服务、轮转法、多级反馈队列列算法、优先级法、短作业优先法、最高响应 |
|
5 |
如何编程实现作业调度算法? |
|
|
6 |
模拟程序的输入如何设计更方便、结果输出如何呈现更好? |
|
|
五、 其他要求
1. 完成报告书,内容完整,规格规范。
2. 实验须检查,回答实验相关问题。
注:带**号的条目表示选做内容。
二、实验内容
根据指定的实验课题,完成设计、编码和调试工作,完成实验报告。
三、实验环境
可以采用TC,也可以选用Windows下的利用各种控件较为方便的VB,VC等可视化环境。也可以自主选择其他实验环境。
四、实验原理及核心算法参考程序段
单道FCFS算法:
1 #include<stdio.h> 2 #include<string.h> 3 void shuru(); 4 void readfiles(); 5 void ran(); 6 typedef struct jcb 7 { 8 char name[10]; 9 char status; //状态:开始s,等待d,就绪j 10 int id; 11 int arrtime; //到达时间 12 int reqtime; //要求服务时间 13 int startime; //开始时间 14 int finitime; //完成时间 15 16 float TAtime,TAWtime; //周转时间、带权周转时间 17 float prio; //优先级 18 float HRRF; //响应比 19 20 }jcb; 21 22 23 24 jcb jcbs[100]; //最多100个作业 25 int systime=0,bfsum,add,del; 26 int intarr,infin,intjob,sumjcb; 27 char T='A'; //T的默认值是A 28 29 void sort(int choose) //排序 30 { 31 int i,j; 32 jcb temp; 33 for(i=1;i<=sumjcb;i++) 34 { 35 for(j=i+1;j<=sumjcb;j++) 36 { 37 if(choose==1) 38 { 39 if(jcbs[i].arrtime>jcbs[j].arrtime) 40 { 41 strcpy(temp.name,jcbs[i].name); 42 temp.status=jcbs[i].status; 43 temp.arrtime=jcbs[i].arrtime; 44 temp.reqtime=jcbs[i].reqtime; 45 temp.startime=jcbs[i].startime; 46 temp.finitime=jcbs[i].finitime; 47 temp.TAtime=jcbs[i].TAtime; 48 temp.TAWtime=jcbs[i].TAWtime; 49 temp.prio=jcbs[i].prio; 50 temp.id=jcbs[i].id; 51 temp.HRRF=jcbs[i].HRRF; 52 53 strcpy(jcbs[i].name,jcbs[j].name); 54 jcbs[i].status=jcbs[j].status; 55 jcbs[i].arrtime=jcbs[j].arrtime; 56 jcbs[i].reqtime=jcbs[j].reqtime; 57 jcbs[i].startime=jcbs[j].startime; 58 jcbs[i].finitime=jcbs[j].finitime; 59 jcbs[i].TAtime=jcbs[j].TAtime; 60 jcbs[i].TAWtime=jcbs[j].TAWtime; 61 jcbs[i].prio=jcbs[j].prio; 62 jcbs[i].id=jcbs[j].id; 63 jcbs[i].HRRF=jcbs[j].HRRF; 64 65 strcpy(jcbs[j].name,temp.name); 66 jcbs[j].status=temp.status; 67 jcbs[j].arrtime=temp.arrtime; 68 jcbs[j].reqtime=temp.reqtime; 69 jcbs[j].startime=temp.startime; 70 jcbs[j].finitime=temp.finitime; 71 jcbs[j].TAtime=temp.TAtime; 72 jcbs[j].TAWtime=temp.TAWtime; 73 jcbs[j].prio=temp.prio; 74 jcbs[j].id=temp.id; 75 jcbs[j].HRRF=temp.HRRF; 76 } 77 } 78 else if(choose==2) 79 { 80 if(jcbs[i].reqtime>jcbs[j].reqtime) 81 { 82 strcpy(temp.name,jcbs[i].name); 83 temp.status=jcbs[i].status; 84 temp.arrtime=jcbs[i].arrtime; 85 temp.reqtime=jcbs[i].reqtime; 86 temp.startime=jcbs[i].startime; 87 temp.finitime=jcbs[i].finitime; 88 temp.TAtime=jcbs[i].TAtime; 89 temp.TAWtime=jcbs[i].TAWtime; 90 temp.prio=jcbs[i].prio; 91 temp.id=jcbs[i].id; 92 temp.HRRF=jcbs[i].HRRF; 93 94 strcpy(jcbs[i].name,jcbs[j].name); 95 jcbs[i].status=jcbs[j].status; 96 jcbs[i].arrtime=jcbs[j].arrtime; 97 jcbs[i].reqtime=jcbs[j].reqtime; 98 jcbs[i].startime=jcbs[j].startime; 99 jcbs[i].finitime=jcbs[j].finitime; 100 jcbs[i].TAtime=jcbs[j].TAtime; 101 jcbs[i].TAWtime=jcbs[j].TAWtime; 102 jcbs[i].prio=jcbs[j].prio; 103 jcbs[i].id=jcbs[j].id; 104 jcbs[i].HRRF=jcbs[j].HRRF; 105 106 strcpy(jcbs[j].name,temp.name); 107 jcbs[j].status=temp.status; 108 jcbs[j].arrtime=temp.arrtime; 109 jcbs[j].reqtime=temp.reqtime; 110 jcbs[j].startime=temp.startime; 111 jcbs[j].finitime=temp.finitime; 112 jcbs[j].TAtime=temp.TAtime; 113 jcbs[j].TAWtime=temp.TAWtime; 114 jcbs[j].prio=temp.prio; 115 jcbs[j].id=temp.id; 116 jcbs[j].HRRF=temp.HRRF; 117 } 118 } 119 else if(choose==3) 120 { 121 if(jcbs[i].HRRF<jcbs[j].HRRF) 122 { 123 strcpy(temp.name,jcbs[i].name); 124 temp.status=jcbs[i].status; 125 temp.arrtime=jcbs[i].arrtime; 126 temp.reqtime=jcbs[i].reqtime; 127 temp.startime=jcbs[i].startime; 128 temp.finitime=jcbs[i].finitime; 129 temp.TAtime=jcbs[i].TAtime; 130 temp.TAWtime=jcbs[i].TAWtime; 131 temp.prio=jcbs[i].prio; 132 temp.id=jcbs[i].id; 133 temp.HRRF=jcbs[i].HRRF; 134 135 strcpy(jcbs[i].name,jcbs[j].name); 136 jcbs[i].status=jcbs[j].status; 137 jcbs[i].arrtime=jcbs[j].arrtime; 138 jcbs[i].reqtime=jcbs[j].reqtime; 139 jcbs[i].startime=jcbs[j].startime; 140 jcbs[i].finitime=jcbs[j].finitime; 141 jcbs[i].TAtime=jcbs[j].TAtime; 142 jcbs[i].TAWtime=jcbs[j].TAWtime; 143 jcbs[i].prio=jcbs[j].prio; 144 jcbs[i].id=jcbs[j].id; 145 jcbs[i].HRRF=jcbs[j].HRRF; 146 147 strcpy(jcbs[j].name,temp.name); 148 jcbs[j].status=temp.status; 149 jcbs[j].arrtime=temp.arrtime; 150 jcbs[j].reqtime=temp.reqtime; 151 jcbs[j].startime=temp.startime; 152 jcbs[j].finitime=temp.finitime; 153 jcbs[j].TAtime=temp.TAtime; 154 jcbs[j].TAWtime=temp.TAWtime; 155 jcbs[j].prio=temp.prio; 156 jcbs[j].id=temp.id; 157 jcbs[j].HRRF=temp.HRRF; 158 } 159 } 160 else 161 printf("Error!\n"); 162 } 163 } 164 } 165 void ins() //插入 166 { 167 int i; 168 while(T!='E'&&T!='e') 169 { 170 printf("'I'nsert or 'D'elete or 'E'xit?\n"); 171 getchar(); 172 scanf("%c",&T); 173 if(T=='I'||T=='i') 174 { 175 printf("你想插入多少个作业?\n"); 176 scanf("%d",&add); 177 bfsum=sumjcb; 178 sumjcb=sumjcb+add; 179 for(i=bfsum+1;i<=sumjcb;i++) 180 { 181 printf("\n第%d个作业:\n",i); 182 getchar(); 183 printf("输入作业名:\n"); 184 gets(jcbs[i].name); 185 printf("到达时间:\n"); 186 scanf("%d",&jcbs[i].arrtime); 187 printf("要求服务时间:\n"); 188 scanf("%d",&jcbs[i].reqtime); 189 } 190 } 191 else if(T=='D'||T=='d') 192 { 193 printf("你想删除第几组?"); 194 scanf("%d",&del); 195 for(i=del;i<=sumjcb-1;i++) 196 { 197 strcpy(jcbs[i].name,jcbs[i+1].name); 198 jcbs[i].arrtime=jcbs[i+1].arrtime; 199 jcbs[i].reqtime=jcbs[i+1].reqtime; 200 } 201 sumjcb--; 202 } 203 } 204 } 205 206 207 void printarr() //打印 208 { 209 int i; 210 printf("\t\tname\tartime\trqtime\n"); 211 for(i=1;i<=sumjcb;i++) 212 { 213 printf("N %d\t",i); 214 printf("\t%s",jcbs[i].name); 215 printf("\t%d",jcbs[i].arrtime); 216 printf("\t%d\n",jcbs[i].reqtime); 217 } 218 printf("\t\t\t\t\t\t现在系统时间%d\n",systime); 219 220 } 221 void printz() 222 { 223 int i; 224 float sum1=0,sum2=0; //计算平均周转时间、平均带权周转时间 225 printf("\t\tname\tartime\trqtime\tstime\tftime\tTAtime\t\tTAWtime\n"); 226 for(i=1;i<=sumjcb;i++) 227 { 228 printf("N %d\t",i); 229 printf("\t%s",jcbs[i].name); 230 printf("\t%d",jcbs[i].arrtime); 231 printf("\t%d",jcbs[i].reqtime); 232 printf("\t%d",jcbs[i].startime); 233 printf("\t%d",jcbs[i].finitime); 234 printf("\t%f",jcbs[i].TAtime); 235 printf("\t%f\n",jcbs[i].TAWtime); 236 } 237 for(i=1;i<=sumjcb;i++) 238 { 239 sum1=sum1+jcbs[i].TAtime; 240 } 241 for(i=1;i<=sumjcb;i++) 242 { 243 sum2=sum2+jcbs[i].TAWtime; 244 } 245 printf("\n平均周转时间=%f\n",sum1/sumjcb); 246 printf("\n平均带权周转时间=%f\n",sum2/sumjcb); 247 printf("\t\t\t\t\t\t现在系统时间%d\n",systime); 248 } 249 void sumofthey() 250 { 251 int i; 252 jcbs[1].startime=jcbs[1].arrtime; 253 jcbs[1].finitime=jcbs[1].arrtime+jcbs[1].reqtime; 254 jcbs[1].TAtime=(float)(jcbs[1].finitime-jcbs[1].arrtime); 255 jcbs[1].TAWtime=(float)(jcbs[1].TAtime/jcbs[1].reqtime); 256 jcbs[1].HRRF=(float)(jcbs[1].TAtime/jcbs[1].reqtime); 257 for(i=2;i<=sumjcb;i++) 258 { 259 jcbs[i].startime=jcbs[i-1].finitime; 260 jcbs[i].finitime=jcbs[i].startime+jcbs[i].reqtime; 261 jcbs[i].TAtime=(float)(jcbs[i].finitime-jcbs[i].arrtime); 262 jcbs[i].TAWtime=(float)(jcbs[i].TAtime/jcbs[i].reqtime); 263 jcbs[i].HRRF=(float)(jcbs[i].TAtime/jcbs[i].reqtime); 264 } 265 } 266 void startit() 267 { 268 int n; 269 printf("\n"); 270 printf("\t\t\t**************************\n"); 271 printf("\t\t\t**1.调用文本写入数据******\n"); 272 printf("\t\t\t**2.调用伪随机数产生数据**\n"); 273 printf("\t\t\t**3.调用自己输入模拟数据**\n"); 274 printf("\t\t\t**************************\n"); 275 scanf("%d",&n); 276 switch(n) 277 { 278 case 1: 279 readfiles(); 280 sumofthey(); 281 break; 282 case 2: 283 ran(); 284 sumofthey(); 285 break; 286 case 3: 287 shuru(); 288 sumofthey(); 289 break; 290 default: 291 { 292 printf("输入有误,请重新输入"); 293 break; 294 } 295 } 296 } 297 void ran() 298 { 299 int i; 300 srand((unsigned)time(0)); //参数seed是rand()的种子,用来初始化rand()的起始值。 301 sumjcb=rand()%23+5; 302 for(i=1;i<=sumjcb;i++) 303 { 304 itoa(i,jcbs[i].name, 2); 305 306 jcbs[i].arrtime=rand()%29+1; 307 308 jcbs[i].reqtime=rand()%7+1; 309 } 310 printf("\n \tid \t作业到达时间 \t作业运行所需要时间\n"); 311 for(i=1; i<=sumjcb; i++) 312 { 313 printf("\n\t%s\t%12d\t%15d",jcbs[i].name,jcbs[i].arrtime,jcbs[i].reqtime); 314 } 315 printf("\n"); 316 } 317 318 void readfiles() 319 { 320 char szTest[1000] = {0};int i=0,n; 321 FILE *fp=fopen("D:\\File1.txt","r"); 322 //FILE *fout=fopen("D:\\File2.txt","w"); 323 if(fp == NULL) 324 { 325 printf("ERROR!\n"); 326 exit(0); 327 } 328 //fscanf(fp,"jcbsum=%d\n",%n); 329 while(!feof(fp)) 330 { 331 fscanf(fp,"%d%d%d",&jcbs[i].id,&jcbs[i].arrtime,&jcbs[i].reqtime); //fscanf()函数将数据读入 332 printf("\n%3d%12d%15d\n",jcbs[i].id,jcbs[i].arrtime,jcbs[i].reqtime); //输出到屏幕 333 itoa(jcbs[i].id,jcbs[i].name,10); 334 i++; 335 /*memset(szTest, 0, sizeof(szTest)); 336 fscanf(fp,"@id=%d|",&i); 337 fgets(fp,"name=%s|",jcbs[i].name); 338 fscanf(fp,"arrtime=%d|reqtime=%d\n",&jcbs[i].arrtime,&jcbs[i].reqtime); 339 */ 340 //fscanf(fp,"%d",) 341 } 342 sumjcb=i; 343 fclose(fp); 344 } 345 void shuru() 346 { 347 int i; 348 printf("作业个数:\n"); 349 scanf("%d",&sumjcb); 350 for(i=1;i<=sumjcb;i++) 351 { 352 printf("\n第%d个作业:\n",i); 353 getchar(); 354 printf("输入作业名:\n"); 355 gets(jcbs[i].name); 356 printf("到达时间:\n"); 357 scanf("%d",&jcbs[i].arrtime); 358 printf("要求服务时间:\n"); 359 scanf("%d",&jcbs[i].reqtime); 360 } 361 sumofthey(); 362 } 363 void choosesort() 364 { 365 int n; 366 printf("\t\t\t*****************************\n"); 367 printf("\t\t\t*******1.FCFS算法调度********\n"); 368 printf("\t\t\t*******2.SJF算法调度*********\n"); 369 printf("\t\t\t*******3.HRRF算法调度********\n"); 370 printf("\t\t\t*******4.调用系统清屏********\n"); 371 printf("\t\t\t*******5.退出算法调度********\n"); 372 printf("\t\t\t*****************************\n"); 373 scanf("%d",&n); 374 switch(n) 375 { 376 case 1: 377 printf("运行先来先服务算法FCFS\n"); 378 sort(1); 379 printf("\n经按到达时间排序后,未达到队列是\n"); 380 printz(); 381 break; 382 case 2: 383 printf("运行最短作业优先算法FJS\n"); 384 sort(2); 385 printf("\n经按到达时间排序后,未达到队列是\n"); 386 printz(); 387 break; 388 case 3: 389 printf("运行最高响应比优先算法HRRF\n"); 390 sort(3); 391 printf("\n经按到达时间排序后,未达到队列是\n"); 392 printz(); 393 break; 394 case 4: 395 system("cls"); 396 break; 397 case 5: 398 exit(0); 399 break; 400 } 401 } 402 void main() 403 { 404 startit(); 405 choosesort(); 406 407 408 }