实验1、做业调度模拟程序实验html
商业软件工程 杨晶晶 201406114102node
1、 实验目的算法
(1)加深对做业调度算法的理解;编程
(2)进行程序设计的训练。数据结构
2、 实验内容和要求并发
实验内容
根据指定的实验课题,完成设计、编码和调试工做,完成实验报告。dom
实验要求函数
用高级语言编写一个或多个做业调度的模拟程序。post
单道批处理系统的做业调度程序。做业一投入运行,它就占有计算机的一切资源直到做业完成为止,所以调度做业时没必要考虑它所须要的资源是否获得知足,它所运行的时间等因素。测试
1、 模拟数据的生成
1. 容许用户指定做业的个数(2-24),默认值为5。
2. 容许用户选择输入每一个做业的到达时间和所需运行时间。
3. (**)从文件中读入以上数据。
4. (**)也容许用户选择经过伪随机数指定每一个做业的到达时间(0-30)和所需运行时间(1-8)。
2、 模拟程序的功能
1. 按照模拟数据的到达时间和所需运行时间,执行FCFS, SJF和HRRN调度算法,程序计算各做业的开始执行时间,各做业的完成时间,周转时间和带权周转时间(周转系数)。
2. 动态演示每调度一次,更新如今系统时刻,处于运行状态和等待各做业的相应信息(做业名、到达时间、所需的运行时间等)对于HRRN算法,能在每次调度时显示各做业的响应比R状况。
3. (**)容许用户在模拟过程当中提交新做业。
4. (**)编写并调度一个多道程序系统的做业调度模拟程序。 只要求做业调度算法:采用基于先来先服务的调度算法。 对于多道程序系统,要假定系统中具备的各类资源及数量、调度做业时必须考虑到每一个做业的资源要求。
3、 模拟数据结果分析
1. 对同一个模拟数据各算法的平均周转时间,周转系数比较。
2. (**)用曲线图或柱形图表示出以上数据,分析算法的优势和缺点。
4、 实验准备
序号 |
准备内容 |
完成状况 |
1 |
什么是做业? |
做业至关于一个程序。 任务至关于整个程序中的一段段能够并发执行的代码。 进程其实就是任务。从系统的角度看,做业则是一个比程序更广的概念。它由程序、数据和做业说明书组成。系统经过做业说明书控制文件形式的程序和数据,使之执行和操做。并且,在批处理系统中,做业是抢占内存的基本单位。也就是说,批处理系统以做业为单位把程序和数据调入内存以便执行。 |
2 |
一个做业具有什么信息? |
做业由三部分组成,即程序、数据和做业说明书。一个做业能够包含多个程序和多个数据集,但必须至少包含一个程序。不然将不成为做业。 |
3 |
为了方便模拟调度过程,做业使用什么方式的数据结构存放和表示? |
由做业说明书在系统中生成一个称为做业控制块(job control block,JCB)的表格。该表格登记该做业所要求的资源状况、预计执行时间和执行优先级等。从而,操做系统经过该表了解到做业要求,并分配资源和控制做业中程序和数据的编译、连接、装入和执行等。 |
4 |
操做系统中,经常使用的做业调度算法有哪些? |
先来先服务算法、最短做业优先算法、最短剩余时间优先算法、最高响应比优先算法、轮转调度算法、多级反馈队列调度算法、优先级法调度算法 |
5 |
如何编程实现做业调度算法? |
|
6 |
模拟程序的输入如何设计更方便、结果输出如何呈现更好? |
|
5、 其余要求
1. 完成报告书,内容完整,规格规范。
2. 实验须检查,回答实验相关问题。
注:带**号的条目表示选作内容。
实验原理及核心算法参考程序段
单道FCFS算法:
3、 实验方法、步骤及结果测试
1. 源程序名:源程序名 job2.c
可执行程序名:job2.exe
2. 原理分析及流程图
做业调度算法:
1) 采用先来先服务(FCFS)调度算法,即按做业到达的前后次序进行调度。老是首先调度在系统中等待时间最长的做业。
2) 短做业优先 (SJF) 调度算法,优先调度要求运行时间最短的做业。
3) 响应比高者优先(HRRN)调度算法,为每一个做业设置一个优先权(响应比),调度以前先计算各做业的优先权,优先数高者优先调度。RP (响应比)= 做业周转时间 / 做业运行时间=1+做业等待时间/做业运行时间
每一个做业由一个做业控制块JCB表示,JCB能够包含如下信息:做业名、提交(到达)时间、所需的运行时间、所需的资源、做业状态、链指针等等。
做业的状态能够是等待W(Wait)、运行R(Run)和完成F(Finish)三种之一。每一个做业的最初状态都是等待W。
3. 主要程序段及其解释:
1 #include<stdio.h> 2 #include <stdlib.h> 3 #include <time.h> 4 #define MAX 24 5 typedef struct node 6 { 7 char name[10];//做业名 8 int arrivetime;//做业到达时间 9 int requesttime;//做业要求服务时间 10 int starttime; //开始时间 11 int finishtime; //结束时间 12 float Ttime;//周转时间 13 float p;//响应比 14 float Wtime;//带权周转时间 15 }JCB; 16 17 static int N=5; //系统默认做业数 18 static int flag=0; 19 JCB job[MAX]; 20 21 void FCFS();//先来先服务算法 22 void SJF();//最短做业优先算法 23 void HRRN();//最高响应比优先算法 24 void getValue();//给每一个做业内的相关参数赋值 25 void input();//输入数据 26 void print();//打印输入的数据列表 27 void getp();//获得响应比 28 int ReadFile();//读取文件中的数据 29 void input1();//初始数据列表 30 31 //读取文件数据 32 int ReadFile() 33 { 34 int m=0; 35 char i=0; 36 FILE *fp; //定义文件指针 37 fp=fopen("3.txt","r"); //打开文件 38 if(fp==NULL) 39 { 40 printf("File open error !\n"); 41 exit(0); 42 } 43 printf("\n文件中的数据内容为:"); 44 while(!feof(fp)) 45 { 46 47 fscanf(fp,"\n%s%d%d",&job[i].name,&job[i].arrivetime,&job[i].requesttime); //fscanf()函数将数据读入 48 printf("\n%3d%12d%15d",job[i].name,job[i].arrivetime,job[i].requesttime); //输出到屏幕 49 i++; 50 }; 51 printf("\n"); 52 if(fclose(fp)) //关闭文件 53 { 54 printf("Can not close the file !\n"); 55 exit(0); 56 } 57 m=i-1; 58 return m; 59 60 } 61 62 //伪随机数产生器 63 int Pseudo_random_number() 64 { 65 int i,n; 66 srand((unsigned)time(0)); //参数seed是rand()的种子,用来初始化rand()的起始值。 67 //输入做业数 68 n=rand()%23+5; 69 for(i=0; i<=n; i++) 70 { 71 //做业到达时间 72 job[i].arrivetime=rand()%29+1; 73 //做业运行时间 74 job[i].requesttime=rand()%7+1; 75 } 76 return n; 77 78 } 79 80 void input1() 81 { 82 int i; 83 printf("\n--------输入的数据为:\n"); 84 printf(" 做业名 到达时间 要求服务时间\n"); 85 for(i=0; i<N; i++) 86 { 87 printf("第%d个做业",i+1); 88 printf(" %4s% 13d %14d\n",job[i].name,job[i].arrivetime,job[i].requesttime); 89 } 90 } 91 92 void input()//输入数据 93 { 94 int i, jobNum, choi; 95 char flag=0; 96 printf("_________________________________\n"); 97 printf("1.自选做业个数并输入\n"); 98 printf("2.伪随机数产生器\n"); 99 printf("3.读取文件输入数据\n"); 100 printf("_________________________________\n"); 101 printf("****你的选择是:"); 102 scanf("%d", &choi); 103 switch(choi) 104 { 105 case 1: 106 { 107 do{ 108 printf("****请输入做业个数(个数在2~24之间):"); 109 scanf("%d", &jobNum); //输入做业数 110 N=jobNum; 111 112 113 } 114 while(N<2 || N>24); 115 break; 116 } 117 case 2: 118 Pseudo_random_number();//产生随机数 119 //input1(); 120 break; 121 case 3: 122 ReadFile();//读取文件 123 //input1(); 124 break; 125 default: 126 printf("\n !!!!!输入错误,请从新选择!!!!!\n"); 127 input(); 128 129 } 130 for(i=0; i<jobNum; i++) 131 { 132 printf("\n第%d个做业名:",i+1); 133 scanf(" "); 134 gets(job[i].name); //输入做业名 135 printf("到达时间:"); 136 scanf(" %d",&job[i].arrivetime); //输入做业达到时间 137 printf("要求服务时间:"); 138 scanf(" %d",&job[i].requesttime); //输入做业要求服务时间 139 job[i].starttime=0; 140 141 } 142 input1(); 143 } 144 145 void print()//打印输入的数据列表 146 { 147 int i; 148 float TAvetime; 149 float WAvetime; 150 float TtimeSum=0; 151 float WtimeSum=0; 152 153 printf(" 做业名 到达时间 要求服务时间 开始时间 完成时间 周转时间 带权周转时间\n"); 154 for(i=0; i<N; i++) 155 { 156 TtimeSum+=job[i].Ttime; 157 WtimeSum+=job[i].Wtime; 158 printf("第%d个做业",i+1); 159 printf(" %4s% 13d %14d %9d %10d %10.2f %10.2f\n",job[i].name,job[i].arrivetime,job[i].requesttime,job[i].starttime,job[i].finishtime,job[i].Ttime,job[i].Wtime); 160 161 } 162 TAvetime=TtimeSum/N; 163 WAvetime=WtimeSum/N; 164 printf("平均周转时间为:%.2f",TAvetime); 165 printf("\n平均带权周转时间为:%.2f",WAvetime); 166 } 167 168 void choice()//选择调度算法 169 { 170 int mark; 171 printf("\n\n--------------------------------------------- "); 172 printf("\n 1.先来先服务(FCFS)调度算法;"); 173 printf("\n 2.最短做业优先(SJF)调度算法;"); 174 printf("\n 3.最高响应比优先(HRRF)调度算法; "); 175 printf("\n 4.退出; "); 176 printf("\n 5.返回主菜单 "); 177 printf("\n---------------------------------------------\n"); 178 printf("\n 请选择算法: "); 179 scanf("%d", &mark); 180 switch(mark) 181 { 182 case 1: 183 printf("\n********************先来先服务(FCFS)调度算法结果*****************\n\n"); 184 FCFS(); //先来先服务算法 185 choice(); 186 break; 187 case 2: 188 printf("\n********************最短做业优先(SJF)调度算法结果*****************\n\n"); 189 SJF(); //最短做业优先算法 190 choice(); 191 break; 192 case 3: 193 printf("\n********************最高响应比优先(HRRF)调度算法结果*****************\n\n"); 194 HRRN(); //最高响应比优先算法 195 choice(); 196 break; 197 case 4: 198 return; 199 case 5: 200 input(); 201 choice(); 202 break; 203 default: 204 printf("\n !!!!!!输入错误,请从新选择!!!!!!"); 205 choice(); 206 } 207 } 208 209 void getValue() //给每一个做业内的相关参数赋值 210 { 211 int i; 212 213 for(i=0; i<N; i++) 214 { 215 if(i==0 || job[i].arrivetime>job[i-1].finishtime) 216 job[i].starttime=job[i].arrivetime; 217 else 218 job[i].starttime=job[i-1].finishtime; 219 job[i].finishtime=job[i].requesttime+job[i].starttime; 220 job[i].Ttime=(float)job[i].finishtime-(float)job[i].arrivetime; 221 job[i].Wtime=(float)job[i].Ttime/(float)job[i].requesttime; 222 223 } 224 } 225 226 void FCFS()//先来先服务算法 227 { 228 int i, j; 229 JCB mark; 230 for(i=0;i<N-1; i++) //经过做业到达时间总体排序 231 { 232 for(j=i+1; j<N; j++) 233 { 234 if(job[j].arrivetime<job[i].arrivetime)//冒泡排序 235 { 236 mark=job[j]; 237 job[j]=job[i]; 238 job[i]=mark; 239 } 240 } 241 } 242 getValue();//给每一个做业内的相关参数赋值 243 print(); //打印出结果 244 } 245 246 void SJF()//最短做业优先算法 247 { 248 int i, j; 249 JCB mark; 250 for(i=1;i<N-1; i++) //经过做业所需运行时间总体排序 251 { 252 for(j=i+1; j<N; j++) 253 { 254 if(job[j].requesttime<job[i].requesttime)//冒泡排序 255 { 256 mark=job[j]; 257 job[j]=job[i]; 258 job[i]=mark; 259 } 260 } 261 } 262 263 getValue(); //给每一个做业内的相关参数赋值 264 print(); //打印出结果 265 266 } 267 268 void HRRN()//最高响应比优先算法 269 { 270 int i, j; 271 JCB mark; 272 for(i=1;i<N-1; i++) //经过到达时间总体排序 273 { 274 for(j=i+1; j<N; j++) 275 { 276 if(job[j].arrivetime<job[i].arrivetime) 277 { 278 mark=job[j]; 279 job[j]=job[i]; 280 job[i]=mark; 281 } 282 } 283 } 284 job[0].starttime=job[0].arrivetime; 285 job[0].finishtime=job[0].requesttime+job[0].starttime;; 286 job[0].Ttime=job[0].finishtime-job[0].arrivetime; 287 job[0].Wtime=(float)job[0].Ttime/(float)job[0].requesttime; 288 289 flag=0; 290 getp(); // 获得响应比 291 print(); //打印出来 292 } 293 294 void getp()//获得响应比 295 { 296 int i, j; 297 JCB mark2; 298 do{ 299 for(i=flag+1; i<N; i++) 300 { 301 if(job[i].arrivetime>job[flag].finishtime) //后面的与第一个对比 302 job[i].starttime=job[i].arrivetime; 303 else 304 job[i].starttime=job[flag].finishtime; 305 job[i].finishtime=job[i].requesttime+job[i].starttime; 306 job[i].Ttime=job[i].finishtime-job[i].arrivetime; 307 job[i].Wtime=(float)job[i].Ttime/(float)job[i].requesttime; 308 } 309 for(i=flag+1;i<N-1; i++) //后面的元素 根据响应比总体排序 获得高响应比的元素 310 { 311 for(j=i+1; j<N; j++) 312 { 313 if(job[j].Wtime>job[i].Wtime) 314 { 315 mark2=job[j]; 316 job[j]=job[i]; 317 job[i]=mark2; 318 } 319 } 320 } 321 flag++; 322 }while(flag<N); 323 } 324 325 void main() 326 { 327 printf("\n*************************欢迎使用做业调度模拟程序*************************\n\n"); 328 input(); //输入 329 //print(); //打印输出 330 choice(); //选择调度算法 331 }
4. 运行结果及分析
4、 实验总结
此次的实验作的时间挺长的,主要实现了三种做业调度算法,还能够经过产生随机数来产生数据。一开始的代码都写在main函数里面,看起来不美观并且不方便,因此把代码都分开放到不一样的方法里面,改起来会比较方便。在实现最短做业优先算法的时候一开始忽略了第一个做业是最早到达,并且只有一个做业在调度,无论其余的做业时间有多短都应该先运行做业一。在实现最高响应比优先算法的时候,虽然知道怎么比较计算响应比,但是不太会实现算法让他们进行做业调度,后来向同窗求助还有上网参考一些代码实现。这过程有不少粗心的地方,好比计算公式错了,原本是整形,输出却打印浮点型的数,弄得一直是显示0。之后要多练习多注意细节问题。