实验二、作业调度实验
专业 计算机科学与技术 姓名 胡洁如 学号 201306114125
一、 实验目的
(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. 对同一个模拟数据各算法的平均周转时间,周转系数比较。
2. (**)用曲线图或柱形图表示出以上数据,分析算法的优点和缺点。
四、 其他要求
1. 完成报告书,内容完整,规格规范。
2. 实验须检查,回答实验相关问题。
注:带**号的条目表示选做内容。
三、 实验方法、步骤及结果测试
源程序名:作业调度.cpp
- 1. 原理分析及流程图
存储结构:结构体数组。
主要算法:排序算法跟最大值算法
关键函数:循环嵌套
- 2. 主要程序段及其解释:
看提交的代码
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include <conio.h> 4 5 6 struct Job { 7 //定义作业控制块JCB 8 char name[10]; //作业名 9 float subtime; //作业提交时间 10 float runtime; //作业所需的运行时间 11 12 float Tb; //作业运行时刻 13 float Tc; //作业完成时刻 14 float Ti; //周转时间 15 float Wi; //带权周转时间 16 17 }; 18 struct Job job[24]={0}; 19 20 int input(Job *j,int n);//输入作业内容 21 void output(Job *j,int n);//输出作业内容 22 void FCFS(Job *j,int n); 23 float addallruntime(Job *j,int n);//得到总的时间 24 void SJF(Job *j,int n,float allruntime); 25 void HRRF(Job *j,int n,float allruntime); 26 int main() 27 { 28 int n=0; 29 int i; 30 float a=0.0,b=0.0;//a存放作业平均周转时间,b存放平均带权周转时间 31 float allruntime=0.0; 32 printf("*********欢迎使用作业调度模拟系统***********\n"); 33 n=input(job,n); 34 allruntime=addallruntime(job,n); 35 36 printf("\n1.FCFS 2.SJF 3.HRN"); 37 printf("\n请选择作业调度算法:"); 38 scanf("%d",&i); 39 if(i==1) 40 { 41 FCFS(job,n); 42 } 43 else if(i==2) 44 { 45 SJF(job,n,allruntime); 46 }else if(i==3) 47 { 48 HRRF(job,n,allruntime); 49 } 50 else 51 { 52 53 } 54 55 printf("\n*******运行结果*********"); 56 57 output(job,n); 58 for(i=0;i<n;i++) 59 { 60 a=a+job[i].Ti; 61 } 62 a=a/n; 63 printf("\n此调度的平均周转时间:%f",a); 64 for(i=0;i<n;i++) 65 { 66 b=b+job[i].Wi; 67 } 68 b=b/n; 69 printf("\n此调度的带权平均周转时间:%f\n",b); 70 71 return 0; 72 } 73 int input(Job *j,int n)//输入作业 74 { 75 76 int i; 77 printf("请输入作业数:"); 78 scanf("%d",&n); 79 for(i=0;i<n;i++) 80 { 81 printf("\n作业号%d:",i); 82 printf("\n请输入作业名"); 83 scanf("%s",job[i].name); 84 85 86 printf("\n请输入作业提交时刻"); 87 scanf("%f",&job[i].subtime); 88 89 printf("\n请输入作业运行时间"); 90 scanf("%f",&job[i].runtime); 91 92 93 } 94 95 return n; 96 97 } 98 void output(Job *j,int n)//打印输出作业信息 99 100 { 101 int i; 102 printf("\n各个作业的情况"); 103 printf("\n作业名"); 104 105 printf(" 作业运行时刻"); 106 printf(" 作业完成时刻"); 107 printf(" 周转时间"); 108 printf(" 带权周转时间"); 109 110 111 112 for(i=0;i<n;i++) 113 { 114 115 printf("\n%s",j[i].name); 116 117 printf(" %f",j[i].Tb); 118 printf(" %f",j[i].Tc); 119 printf(" %f",j[i].Ti); 120 printf(" %f",j[i].Wi); 121 } 122 123 } 124 125 float addallruntime(Job *j,int n)//得到所有作业运行时间 126 { 127 int i; 128 float allruntime=0.0; 129 for(i=0;i<n;i++) 130 { 131 132 133 allruntime=allruntime+job[i].runtime; 134 } 135 return allruntime; 136 } 137 138 void FCFS(Job *j,int n) 139 { 140 int i; 141 j[0].Tb=j[0].subtime; 142 j[0].Tc=j[0].Tb+j[0].runtime; 143 j[0].Ti=j[0].Tc-j[0].subtime; 144 j[0].Wi=j[0].Ti/j[0].runtime; 145 for(i=1;i<n;i++) 146 { 147 148 j[i].Tb=j[i-1].Tc; 149 j[i].Tc=j[i].Tb+j[i].runtime; 150 j[i].Ti=j[i].Tc-j[i].subtime; 151 j[i].Wi=j[i].Ti/j[i].runtime; 152 153 } 154 } 155 void SJF(Job *j,int n,float allruntime) 156 { 157 float mintime=0; 158 Job jtemp={0}; 159 160 int min=0; 161 162 int startwork=0; 163 float i; 164 int k; 165 for(i=0;i<allruntime;) 166 { 167 mintime=j[startwork].runtime;//假设一个剩余时间的最小值 168 for(k=startwork;k<n;k++) 169 { 170 171 if(j[k].runtime<=mintime&&j[k].subtime<=i)//此作业的剩余时间更少则将其记为最少 172 { 173 mintime=j[k].runtime; 174 min=k; 175 } 176 177 } 178 j[min].Tb=i; 179 180 j[min].Tc=j[min].Tb+j[min].runtime; 181 j[min].Ti=j[min].Tc-j[min].subtime; 182 j[min].Wi=j[min].Ti/j[min].runtime; 183 184 jtemp=j[startwork]; 185 j[startwork]=j[min]; 186 j[min]=jtemp; 187 188 startwork++; 189 190 i=i+mintime; 191 } 192 193 } 194 void HRRF(Job *j,int n,float allruntime) 195 { 196 197 float maxrb=0; 198 Job jtemp={0}; 199 200 int z=0; 201 float time=0; 202 int startwork=0; 203 float i; 204 int k; 205 for(i=0;i<allruntime;) 206 { 207 maxrb=(i-j[startwork].subtime)/j[startwork].runtime+1;//假设是最高响应比 208 209 for(k=startwork;k<n;k++) 210 { 211 212 213 214 if(j[k].subtime<=i&&(i-j[k].subtime)/j[k].runtime+1>=maxrb)//此作业的最高响应比更高,则将其记为更高 215 { 216 time=j[k].runtime; 217 218 z=k; 219 } 220 221 } 222 223 224 j[z].Tb=i; 225 j[z].Tc=j[z].Tb+j[z].runtime; 226 j[z].Ti=j[z].Tc-j[z].subtime; 227 j[z].Wi=j[z].Ti/j[z].runtime; 228 229 jtemp=j[startwork]; 230 j[startwork]=j[z]; 231 j[z]=jtemp; 232 233 234 235 startwork++; 236 i=i+time; 237 } 238 }
- 3. 运行结果及分析
FCFS
SJF
HRRF
结果符合预期
四、 实验总结
拿到实验,首先是先写了结构体,用来储存一个作业的信息,然后是写输入输出,最后写最难的作业调度的算法,整个过程思路还算是清晰的。因为很少用结构体,所以不是很会,就去网上参考了别人的代码。网上有很多作业调度的算法,我觉得看别人的代码有点痛苦,就决定自己写,从中收获了许多知识,对作业调度也有了更加深入的理解。