实验二、作业调度模拟程序
专业:商软二班 姓名:列志华 学号:201406114254
一、目的和要求
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 |
一个作业具备什么信息? |
每个作业由一个作业控制块JCB表示,JCB可以包含以下信息:作业名、提交(到达)时间、所需的运行时间、所需的资源、作业状态、链指针等等。 |
3 |
为了方便模拟调度过程,作业使用什么方式的数据结构存放和表示?JCB |
单个作业使用结构体,多个作业使用队列。 |
4 |
操作系统中,常用的作业调度算法有哪些? |
先来先服务(FCFS)算法,最短作业优先 (SJF)算法,最短剩余时间优先算法,最高响应比优先(HRRN)算法。 |
5 |
如何编程实现作业调度算法? |
先来先服务算法。 |
6 |
模拟程序的输入如何设计更方便、结果输出如何呈现更好? |
输入:读取文件 输出:计算并打印这组作业的平均周转时间及带权周转时间。 |
五、其他要求
1.完成报告书,内容完整,规格规范。
2.实验须检查,回答实验相关问题。
注:带**号的条目表示选做内容。
二、实验内容
根据指定的实验课题,完成设计、编码和调试工作,完成实验报告。
三、实验环境
可以采用TC,也可以选用Windows下的利用各种控件较为方便的VB,VC等可视化环境。也可以自主选择其他实验环境。
四、实验原理及核心算法参考程序段
单道FCFS算法:
源程序:
1 #include<stdio.h> 2 #include<string.h> 3 #include<cstdlib> 4 struct jcb 5 { 6 char name[10]; //作业ID 7 char status; //作业状态 8 9 int arrtime; //作业到达时间 10 int reqtime; //作业要求时间 11 int startime; //作业开始时间 12 int finitime; //作业完成时间 13 14 int reRam; 15 int reqTape; //作业要求磁带机数 16 int reqPrinter; //作业要求打印机数 17 18 float TAtime,TAWtime; 19 float prio; 20 } jobarr[24],jobfin[24],job[24]; 21 22 int systime = 0; 23 int intarr=0,intfin=0,intjod = 0; //作业到达个数,完成作业个数,未到达作业个数 24 25 int RAM = 100 ; 26 int tape = 2 ; 27 int printer = 1 ; 28 29 //按照先来先服务的原则,自动填上作业开始时间,作业完成时间等信息 30 void addInfo() 31 { 32 int i=0; 33 for(i=0 ; i<intjod ; i++) 34 { 35 if(i == 0) 36 { 37 job[i].startime = job[i].arrtime ; 38 job[i].finitime = job[i].reqtime + job[i].arrtime ; 39 } 40 else 41 { 42 if(job[i].arrtime < job[i-1].finitime) 43 { 44 job[i].startime = job[i-1].finitime ; 45 job[i].finitime = job[i].startime + job[i].reqtime ; 46 } 47 else 48 { 49 job[i].startime = job[i].arrtime ; 50 job[i].finitime = job[i].startime + job[i].reqtime ; 51 } 52 } 53 } 54 55 } 56 //对等待队列进行排序操作,按照先来先服务原则 57 void sorting() 58 { 59 struct jcb temp; 60 int i=0,j=0; 61 for(i=0 ; i<intjod ; i++) 62 { 63 for(j=i+1 ; j<intjod ; j++) 64 { 65 if(job[i].arrtime > job[j].arrtime) 66 { 67 temp = job[i]; 68 job[i] = job[j]; 69 job[j] = temp; 70 } 71 } 72 } 73 74 addInfo(); 75 76 77 78 } 79 80 //给等待队列插入一条作业信息 81 void insert() 82 { 83 int i=intjod; 84 printf("第%d插入的作业:",i+1); 85 printf("\n\n第%d个作业:\n",i+1); 86 printf("输入作业名:"); 87 scanf("%s",&job[i].name); 88 printf("到达时间:"); 89 scanf("%d",&job[i].arrtime); 90 printf("要求服务时间:"); 91 scanf("%d",&job[i].reqtime); 92 93 printf("\n要求内存大小:"); 94 scanf("%d",&job[i].reRam); 95 printf("要求磁带机数:"); 96 scanf("%d",&job[i].reqTape); 97 printf("要求打印机数:"); 98 scanf("%d",&job[i].reqPrinter); 99 intjod++; 100 sorting(); 101 102 } 103 //输出等待队列的信息 104 void print() 105 { 106 int i=0; 107 printf("经按到达时间排序后,未到达队列是:\n"); 108 printf("\tname\tarrtime\treqtime\tstartime finitime\treqRam\treqTape\treqPrinter\n"); 109 for(i=0 ; i<intjod ; i++) 110 { 111 printf("N %d\t%s\t%d\t%d\t%d\t %d\t\t%d\t%d\t%d\n",i+1, 112 job[i].name,job[i].arrtime,job[i].reqtime,job[i].startime,job[i].finitime,job[i].reRam,job[i].reqTape,job[i].reqPrinter); 113 } 114 } 115 //手动输入等待队列 116 void scan() 117 { 118 int i=0; 119 printf(" 作业个数:"); 120 scanf("%d",&intjod); 121 for(i=0 ; i<intjod ; i++) 122 { 123 printf("\n\n第%d个作业:\n",i+1); 124 printf("输入作业名:"); 125 scanf("%s",&job[i].name); 126 printf("到达时间:"); 127 scanf("%d",&job[i].arrtime); 128 printf("要求服务时间:"); 129 scanf("%d",&job[i].reqtime); 130 131 printf("\n要求内存大小:"); 132 scanf("%d",&job[i].reRam); 133 printf("要求磁带机数:"); 134 scanf("%d",&job[i].reqTape); 135 printf("要求打印机数:"); 136 scanf("%d",&job[i].reqPrinter); 137 } 138 139 } 140 //对作业队列进行删除操作 141 void dele() 142 { 143 int i =0,j=0; 144 char dleName[10]; 145 printf("请输入要删除的作业的名字:\n"); 146 scanf("%s",&dleName); 147 for(i=0 ; i<intjod ; i++) 148 { 149 if(strcmp(dleName,job[i].name)==0) 150 { 151 for(j=i ; j<intjod ; j++) 152 job[j] = job[j+1] ; 153 154 intjod--; 155 break; 156 } 157 } 158 } 159 160 //开始运行在就绪对列的作业 int intarr,intfin,intjod; 作业到达个数,完成作业个数,未到达作业个数 161 //jobarr[24],jobfin[24],job[24]; 162 void action() 163 { 164 165 166 int i=0; 167 168 if( systime >= job[i].arrtime && RAM >= job[i].reRam && tape >= job[i].reqTape && printer >= job[i].reqPrinter) 169 { 170 job[i].status = 1; 171 jobarr[intarr] = job[i]; 172 for(int j=i ; j<intjod ; j++) 173 { 174 job[j] = job[j+1] ; 175 } 176 intarr++; 177 intjod--; 178 } 179 if(systime >= jobarr[i].finitime) 180 { 181 jobfin[intfin] = jobarr[i] ; 182 intfin++; 183 RAM = RAM+jobarr[i].reRam ; 184 tape = tape+jobarr[i].reqTape ; 185 printer = printer+jobarr[i].reqPrinter; 186 for(int j=i ; j<intjod ; j++) 187 { 188 jobarr[j] = jobarr[j+1] ; 189 } 190 } 191 192 printf("================\n\n当前系统时间:%d\n\n",systime); 193 if(systime >= jobarr[i].arrtime) 194 { 195 printf("作业 %s 开始运行!\n",jobarr[i].name); 196 printf("运行作业\t作业系统时间\tCPU需时/h\t"); 197 printf("\n作业%s\t\t%d\t\t%d",jobarr[i].name,jobarr[i].arrtime,jobarr[i].reqtime); 198 RAM = RAM-jobarr[i].reRam ; 199 tape = tape-jobarr[i].reqTape ; 200 printer = printer-jobarr[i].reqPrinter; 201 202 } 203 printf("\n剩余内存:%d 磁带机:%d 打印机:%d\n\n",RAM,tape,printer); 204 systime++; 205 206 207 } 208 209 void ReadFile() 210 { 211 int m=0; 212 int i=1; 213 FILE *fp; //定义文件指针 214 fp=fopen("3.txt","r"); //打开文件 215 if(fp==NULL) 216 { 217 printf("File open error !\n"); 218 exit(0); 219 } 220 printf("\n id 作业到达时间 作业运行所需要时间\n"); 221 while(!feof(fp)) 222 { 223 fscanf(fp,"%s%d%d",&job[i].name,&job[i].arrtime,&job[i].reqtime); //fscanf()函数将数据读入 224 printf("\n%3s%12d%15d",job[i].name,job[i].arrtime,job[i].reqtime); //输出到屏幕 225 i++; 226 }; 227 228 if(fclose(fp)) //关闭文件 229 { 230 printf("Can not close the file !\n"); 231 exit(0); 232 } 233 m=i-1; 234 intjod = m; 235 236 } 237 238 239 void main() 240 { 241 int flag = 1 ; 242 char ch,cc; 243 printf("请选择输入方式:a.手动 b.文档读入"); 244 scanf("%c",&cc); 245 if(cc == 'a') 246 scan(); 247 else if(cc == 'b') 248 ReadFile(); 249 250 251 sorting(); 252 while(flag) 253 { 254 print(); 255 printf("请输入第一个字符 Insert or Delete or Exit 0r Action or Cls?\n"); 256 scanf(" %c",&ch); 257 if(ch == 'i' || ch == 'I') 258 { 259 insert(); 260 } 261 else if(ch == 'd' || ch == 'D') 262 { 263 dele(); 264 } 265 else if(ch == 'e' || ch == 'E') 266 return ; 267 else if(ch == 'a' || ch == 'A') 268 action(); //开始运行在就绪对列的作业 269 else if(ch == 'c' || ch == 'C') 270 system("cls"); 271 } 272 273 }
五、实验总结
这次试验使用了不同的算法去实现作业调度模拟程序,在学习这些算法的同时,不仅让我学到了很多算法思想,也很好开拓了我们的思维,学会从不同的角度去思考问题和解决问题。主要是理解了作业调度的原理,虽然只是做了先来先服务算法和SJF算法,但是程序大体的框架还是大同小异的。