实验一、作业调度实验
专业:商业软件工程 姓名:杨晓霞 学号:201406114107
一、 实验目的
(1)加深对作业调度算法的理解;
(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.源程序名:作业调度_3.cpp
2. 原理分析及流程图
(1)、存储结构
1 typedef struct JOB{ 2 char jobname[10];//作业的名称 3 int submittime;//作业提交时刻 4 int runtime;//作业运行时间 5 int starttime;//作业开始时刻 6 int finishtime;//作业完成时刻 7 int turnovertime;//作业周转时间 8 float turnnumber;//作业周转系数 9 char jobrun[10];//作业处于运行状态 10 float rp;//作业响应比 11 }job;
(2)、主要程序
int File();
int input();
void sort(int n);
void FCFS(int n)
void SJFsort(int a,int b)
void SJF(int n)
void RP(int a,int b)
void HRRN(int n)
int sand(int n)
3.主要程序段及其解释:
1 void sort(int n) 2 { 3 int i,j; 4 printf("用户输入的原始数据\n"); 5 printf("作业名称\t提交时刻\t运行时间\n"); 6 for(i=0;i<n;i++) 7 { 8 printf("%s\t\t%d\t\t%d\n",jArray[i].jobname,jArray[i].submittime,jArray[i].runtime); 9 } 10 printf("按提交时间排序后,还未进入后备队列的任务!\n"); 11 for(i=0;i<n-1;i++) 12 { 13 for(j=i+1;j<n;j++) 14 { 15 if(jArray[j].submittime<jArray[i].submittime) 16 { 17 temp[j]=jArray[j]; 18 jArray[j]=jArray[i]; 19 jArray[i]=temp[j]; 20 } 21 } 22 } 23 printf("作业名称\t提交时刻\t运行时间\n"); 24 for(i=0;i<n;i++) 25 { 26 printf("%s\t\t%d\t\t%d\n",jArray[i].jobname,jArray[i].submittime,jArray[i].runtime); 27 } 28 } 29 void FCFS(int n) 30 { 31 int time=-1,i=0,j,l,k; 32 float averageround=0.00; 33 float average=0.00; 34 printf("\n\n\n**********先来先服务算法FCFS*************\n"); 35 sort(n); 36 while(i<n) 37 { 38 l=0; 39 while(jArray[i].submittime>time) 40 { 41 l++; 42 time++; 43 printf("\n当前系统时间为:%d\n",time); 44 printf("\n请按任意键继续......"); 45 fflush(stdin); 46 getch(); 47 } 48 if(l==0) 49 { 50 printf("\n当前系统时间为:%d\n",time); 51 printf("\n请按任意键继续......"); 52 fflush(stdin); 53 getch(); 54 } 55 printf("\n还未进入后备队列的作业!\n"); 56 printf("作业名称\t提交时刻\t运行时间\n"); 57 for(j=i+1;j<n;j++) 58 { 59 if(jArray[j].submittime>time) 60 { 61 printf("%s\t\t%d\t\t%d\n",jArray[j].jobname,jArray[j].submittime,jArray[j].runtime); 62 } 63 } 64 printf("\n进入后备队列的作业!\n"); 65 printf("作业名称\t提交时刻\t运行时间\n"); 66 for(j=i;j<n;j++) 67 { 68 if(jArray[j].submittime<=time) 69 { 70 printf("%s\t\t%d\t\t%d\n",jArray[j].jobname,jArray[j].submittime,jArray[j].runtime); 71 } 72 } 73 printf("\n处于运行的作业为:%s\n",jArray[i].jobname); 74 jArray[i].starttime=time; 75 jArray[i].finishtime=jArray[i].starttime+jArray[i].runtime; 76 jArray[i].turnovertime=jArray[i].finishtime-jArray[i].submittime; 77 jArray[i].turnnumber=(float)jArray[i].turnovertime/jArray[i].runtime; 78 time=jArray[i].finishtime; 79 printf("已完成的作业!\n"); 80 printf("\n作业名称 提交时刻 运行时间 开始时刻 完成时间 周转时间 带权周转时间\n"); 81 for(k=0;k<=i;k++) 82 { 83 averageround=averageround+jArray[i].turnovertime; 84 average=average+jArray[i].turnnumber; 85 printf(" %s %d %d %d %d %d %.2f\n\n",jArray[k].jobname,jArray[k].submittime,jArray[k].runtime,jArray[k].starttime,jArray[k].finishtime,jArray[k].turnovertime,jArray[k].turnnumber); 86 } 87 averageround=averageround/n; 88 printf("\n平均作业周转时间=%.2f\n",averageround); 89 average=average/n; 90 printf("\n平均作业带权周转时间=%.2f\n\n\n\n",average); 91 i++; 92 } 93 } 94 void SJFsort(int a,int b) 95 { 96 int i,j; 97 for(i=a;i<b;i++) 98 { 99 for(j=i+1;j<=b;j++) 100 { 101 if(jArray[i].runtime>jArray[j].runtime) 102 { 103 temp[j]=jArray[j]; 104 jArray[j]=jArray[i]; 105 jArray[i]=temp[j]; 106 } 107 } 108 } 109 for(i=a;i<=b;i++) 110 { 111 printf("%s\t\t%d\t\t%d\n",jArray[i].jobname,jArray[i].submittime,jArray[i].runtime); 112 } 113 } 114 void SJF(int n) 115 { 116 int time=-1,i=0,j,l,k,z,a,b; 117 float averageround=0.00; 118 float average=0.00; 119 sort(n); 120 while(i<n) 121 { 122 l=0; 123 z=0; 124 while(jArray[i].submittime>time) 125 { 126 l++; 127 time++; 128 printf("\n当前系统时间为:%d\n",time); 129 printf("\n请按任意键继续......"); 130 fflush(stdin); 131 getch(); 132 } 133 if(l==0) 134 { 135 printf("\n当前系统时间为:%d\n",time); 136 printf("\n请按任意键继续......"); 137 fflush(stdin); 138 getch(); 139 } 140 printf("\n还未进入后备队列的作业!\n"); 141 printf("作业名称\t提交时刻\t运行时间\n"); 142 for(j=i+1;j<n;j++) 143 { 144 if(jArray[j].submittime>time) 145 { 146 printf("%s\t\t%d\t\t%d\n",jArray[j].jobname,jArray[j].submittime,jArray[j].runtime); 147 } 148 } 149 printf("\n进入后备队列的作业!\n"); 150 printf("作业名称\t提交时刻\t运行时间\n"); 151 for(j=i;j<n;j++) 152 { 153 if(jArray[j].submittime<=time) 154 { 155 z++; 156 } 157 } 158 a=i; 159 b=i+z-1; 160 SJFsort(a,b); 161 printf("\n处于运行的作业为:%s\n",jArray[i].jobname); 162 jArray[i].starttime=time; 163 jArray[i].finishtime=jArray[i].starttime+jArray[i].runtime; 164 jArray[i].turnovertime=jArray[i].finishtime-jArray[i].submittime; 165 jArray[i].turnnumber=(float)jArray[i].turnovertime/jArray[i].runtime; 166 time=jArray[i].finishtime; 167 printf("已完成的作业!\n"); 168 printf("\n作业名称 提交时刻 运行时间 开始时刻 完成时间 周转时间 带权周转时间\n"); 169 for(k=0;k<=i;k++) 170 { 171 averageround=averageround+jArray[i].turnovertime; 172 average=average+jArray[i].turnnumber; 173 printf(" %s %d %d %d %d %d %.2f\n\n",jArray[k].jobname,jArray[k].submittime,jArray[k].runtime,jArray[k].starttime,jArray[k].finishtime,jArray[k].turnovertime,jArray[k].turnnumber); 174 } 175 averageround=averageround/n; 176 printf("\n平均作业周转时间=%.2f\n",averageround); 177 average=average/n; 178 printf("\n平均作业带权周转时间=%.2f\n\n\n\n",average); 179 i++; 180 } 181 } 182 void RP(int a,int b) 183 { 184 int i,j; 185 for(i=a;i<b;i++) 186 { 187 for(j=i+1;j<=b;j++) 188 { 189 if(jArray[i].rp<jArray[j].rp) 190 { 191 temp[j]=jArray[j]; 192 jArray[j]=jArray[i]; 193 jArray[i]=temp[j]; 194 } 195 } 196 } 197 for(i=a;i<=b;i++) 198 { 199 printf("%s\t\t%d\t\t%d\n",jArray[i].jobname,jArray[i].submittime,jArray[i].runtime); 200 } 201 } 202 void HRRN(int n) 203 { 204 int time=-1,i=0,j,l,k,z,a,b; 205 float averageround=0.00; 206 float average=0.00; 207 sort(n); 208 while(i<n) 209 { 210 l=0; 211 z=0; 212 while(jArray[i].submittime>time) 213 { 214 l++; 215 time++; 216 printf("\n当前系统时间为:%d\n",time); 217 printf("\n请按任意键继续......"); 218 fflush(stdin); 219 getch(); 220 } 221 if(l==0) 222 { 223 printf("\n当前系统时间为:%d\n",time); 224 printf("\n请按任意键继续......"); 225 fflush(stdin); 226 getch(); 227 } 228 printf("\n还未进入后备队列的作业!\n"); 229 printf("作业名称\t提交时刻\t运行时间\n"); 230 for(j=i+1;j<n;j++) 231 { 232 if(jArray[j].submittime>time) 233 { 234 printf("%s\t\t%d\t\t%d\n",jArray[j].jobname,jArray[j].submittime,jArray[j].runtime); 235 } 236 } 237 printf("\n进入后备队列的作业!\n"); 238 printf("作业名称\t提交时刻\t运行时间\n"); 239 for(j=i;j<n;j++) 240 { 241 if(jArray[j].submittime<=time) 242 { 243 z++; 244 } 245 } 246 a=i; 247 b=i+z-1; 248 for(j=a;j<=b;j++) 249 { 250 jArray[j].finishtime=time+jArray[j].runtime; 251 jArray[j].turnovertime=jArray[j].finishtime-jArray[j].submittime; 252 jArray[j].turnnumber=(float)jArray[j].turnovertime/jArray[j].runtime; 253 jArray[j].rp=1+(float)(time-jArray[j].submittime)/jArray[j].runtime; 254 } 255 RP(a,b); 256 printf("\n处于运行的作业为:%s\n",jArray[i].jobname); 257 jArray[i].starttime=time; 258 jArray[i].finishtime=jArray[i].starttime+jArray[i].runtime; 259 jArray[i].turnovertime=jArray[i].finishtime-jArray[i].submittime; 260 jArray[i].turnnumber=(float)jArray[i].turnovertime/jArray[i].runtime; 261 time=jArray[i].finishtime; 262 printf("已完成的作业!\n"); 263 printf("\n作业名称 提交时刻 运行时间 开始时刻 完成时间 周转时间 带权周转时间\n"); 264 for(k=0;k<=i;k++) 265 { 266 averageround=averageround+jArray[i].turnovertime; 267 average=average+jArray[i].turnnumber; 268 269 printf(" %s %d %d %d %d %d %.2f\n\n",jArray[k].jobname,jArray[k].submittime,jArray[k].runtime,jArray[k].starttime,jArray[k].finishtime,jArray[k].turnovertime,jArray[k].turnnumber); 270 } 271 averageround=averageround/n; 272 printf("\n平均作业周转时间=%.2f\n",averageround); 273 average=average/n; 274 printf("\n平均作业带权周转时间=%.2f\n\n\n\n",average); 275 i++; 276 } 277 } 278 void quit() 279 { 280 printf("谢谢使用该系统!\n"); 281 exit(0); 282 } 283 int File() 284 { 285 int m=0; 286 287 FILE *fp; 288 if((fp=fopen("cmd.txt","a+"))==NULL) 289 { 290 printf("File open error!\n"); 291 exit(0); 292 } 293 printf("\n 作业名称\t提交时刻\t运行时间\n"); 294 while(!feof(fp)&&fgetc(fp)!=EOF) 295 { 296 fseek(fp,-1L,SEEK_CUR); 297 fscanf(fp,"%s%d%d",jArray[count].jobname,&jArray[count].submittime,&jArray[count].runtime); 298 printf("\n%3s%15d%17d",jArray[count].jobname,jArray[count].submittime,jArray[count].runtime); 299 count++; 300 } 301 if(fclose(fp)) 302 { 303 printf("Can not close the file!\n"); 304 exit(0); 305 } 306 m=count-1; 307 return m; 308 309 } 310 int sand(int n) 311 { 312 313 srand((unsigned)time(0)); 314 for(int j=0;j<n;j++) 315 { 316 printf("请输入第%d个作业的名称:",j+1); 317 scanf("%s",jArray[j].jobname); 318 } 319 printf("\n 作业名称\t提交时刻\t运行时间\n"); 320 for(int i=0;i<n;i++) 321 { 322 323 jArray[i].submittime=rand() %24; 324 jArray[i].runtime=rand() %100; 325 printf("\n%3s%15d%17d",jArray[i].jobname,jArray[i].submittime,jArray[i].runtime); 326 327 } 328 329 return n; 330 }
4. 运行结果及分析
四、实验总结
在做这个程序的时候,觉得最难的是当前系统时间表示出来,另外我也用了每个调度算法调用不同的排序函数,在新加入的菜单选项后,觉得文件写入难,因为没怎么用文件写入读取,从开始做到完成花了有十几个小时吧,但还是有不足,有些是参考了别人的。