实验二:作业调度

一、目的和要求

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

4

操作系统中,常用的作业调度算法有哪些?

5

如何编程实现作业调度算法?

6

模拟程序的输入如何设计更方便、结果输出如何呈现更好?

 

五、       其他要求

1.            完成报告书,内容完整,规格规范。

2.            实验须检查,回答实验相关问题。

注:带**号的条目表示选做内容。

二、实验内容

根据指定的实验课题,完成设计、编码和调试工作,完成实验报告。

、实验环境

可以采用TC,也可以选用Windows下的利用各种控件较为方便的VB,VC等可视化环境。也可以自主选择其他实验环境。

四、实验原理及核心算法参考程序段

     单道FCFS算法:

        

源代码:

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<time.h>
  4 struct jcb{
  5     int id;
  6     char status;
  7 
  8     int arrtime;
  9     int reqtime;
 10     int startime;
 11     int finitime;
 12 
 13     float TAtime,TAWtime;
 14     float prio;
 15 }   jobarr[24],jobfin[24],job[24];
 16 int systime=0;
 17 
 18 
 19 //主菜单
 20 void menu()
 21 {
 22     printf("			***************************************
");
 23     printf("			|             作业调度                |
");
 24     printf("			|-------------------------------------|
");
 25     printf("			|  1.调用文本写入数据                 |
");
 26     printf("			|-------------------------------------|
");
 27     printf("			|  2.调用伪随机数的产生数据           |
");
 28     printf("			|-------------------------------------|
");
 29     printf("			|  3.自主输入模拟数据                 |
");
 30     printf("			|**************************************
");
 31 }
 32 
 33 
 34 //调度算法菜单
 35 void menu0()
 36 {
 37     printf("
");
 38     printf("
***************************************
");
 39     printf("      1.FCFS算法调度
");
 40     printf("      2.SJF算法调度
");
 41     printf("      3.HRRF算法调度
");
 42     printf("      4.调用系统清屏
");
 43     printf("      0.退出算法调度
");
 44     printf("***************************************
");
 45 }
 46 
 47 
 48 //短作业优先排序
 49 void sort(int n)
 50 {
 51     int i,j; 
 52     struct jcb temp;
 53     for(i=2;i<n;i++) 
 54     for(j=i+1;j<=n;j++) 
 55     if(jobarr[i].reqtime>jobarr[j].reqtime) //根据最短的要求服务时间排序
 56     { 
 57        temp=jobarr[i]; 
 58        jobarr[i]=jobarr[j]; 
 59        jobarr[j]=temp; 
 60     } 
 61 }
 62 
 63 
 64 //先到先服务排序
 65 void sort0(int n)
 66 {
 67     int i,j; 
 68     struct jcb temp;
 69     for(i=2;i<n;i++) 
 70     for(j=i+1;j<=n;j++) 
 71     if(job[i].arrtime>job[j].arrtime) //根据到达时间排序
 72     { 
 73        temp=job[i]; 
 74        job[i]=job[j]; 
 75        job[j]=temp; 
 76     } 
 77 }
 78 
 79 
 80 //自主输入模拟数据
 81 void shoushu()
 82 {
 83         int n;
 84     printf("作业个数:");
 85     scanf("%d",&n);
 86     for(int i=1;i<=n;i++)
 87     {
 88         printf("
第%d个作业:",i);
 89         printf("
请输入作业名:");
 90         scanf("%d",&job[i].id);
 91         printf("到达时间:");
 92         scanf("%d",&job[i].arrtime);
 93         printf("要求服务时间:");
 94         scanf("%d",&job[i].reqtime);
 95         jobarr[i]=job[i];
 96     }
 97 }
 98 
 99 
100 //文本写入数据
101 int ReadFile()
102 {
103     int m=0;
104     int i=1;
105     FILE *fp;     //定义文件指针
106     fp=fopen("作业调度.txt","r");  //打开文件
107     if(fp==NULL)
108     {
109         printf("File open error !
");
110         exit(0);
111     }
112     printf("
 作业名    作业到达时间     作业运行所需要时间
");
113     while(!feof(fp))
114     {
115         fscanf(fp,"%d%d%d",&job[i].id,&job[i].arrtime,&job[i].reqtime);  //fscanf()函数将数据读入
116         printf("
%3d%12d%15d",job[i].id,job[i].arrtime,job[i].reqtime);  //输出到屏幕
117         i++;
118     };
119 
120     if(fclose(fp))     //关闭文件
121     {
122         printf("Can not close the file !
");
123         exit(0);
124     }
125     m=i-1;
126     return m;
127 
128 }
129 
130 
131 //伪随机数的产生数据
132 int Pseudo_random_number()
133 {
134     int i,n;
135     srand((unsigned)time(0));  //参数seed是rand()的种子,用来初始化rand()的起始值。
136     //输入作业数
137     n=rand()%23+5;
138     for(i=1; i<=n; i++)
139     {
140         job[i].id=i;
141         //作业到达时间
142         job[i].arrtime=rand()%29+1;
143         //作业运行时间
144         job[i].reqtime=rand()%7+1;
145     }
146     printf("
 作业名    作业到达时间     作业运行所需要时间
");
147     for(i=1; i<=n; i++)
148     {
149         printf("
%3d%12d%15d",job[i].id,job[i].arrtime,job[i].reqtime);
150     }
151     return n;
152 
153 }
154 
155 
156 //先来先服务算法FCFS
157 void FCFS()
158 {
159     int i=1,j=1;
160     float sumTA=0,sumTAW=0;
161     printf("-----------先来先服务算法FCFS-------------
");
162     printf("
 作业名    作业到达时间     作业运行所需要时间
");
163     while(job[j].id!=NULL)
164     {
165         printf("
%3d%12d%15d",job[j].id,job[j].arrtime,job[j].reqtime);  //输出到屏幕
166         j++;
167     }
168     sort0(j-1);
169         printf("

作业名   作业到达时间   作业完成时间   运行时间  作业周转时间  带权作业周转时间
");
170         while(job[i].id!=NULL)
171     {
172         if(i==1)  //第一个作业先到达,先被调度
173         {
174             job[i].startime=job[i].arrtime;
175         }
176         else   //其他作业被调度
177         {
178             if(job[i-1].finitime>=job[i].arrtime)  //如果上一个作业的完成时间大于下一个到达时间,则下一个开始时间为上一个作业的完成时间
179                 job[i].startime=job[i-1].finitime;
180             else
181                 job[i].startime=job[i].arrtime;   //否则下一个开始时间即它的到达时间
182         }
183         job[i].finitime=job[i].startime+job[i].reqtime; //计算完成时间
184         job[i].TAtime=job[i].finitime-job[i].arrtime; //计算周转时间
185         job[i].TAWtime=job[i].TAtime/job[i].reqtime;   //计算带权周转时间
186         sumTA+=job[i].TAtime;
187         sumTAW+=job[i].TAWtime;
188         printf("
%3d%12d%13d%14d%12.0lf%14.2lf",job[i].id,job[i].arrtime,job[i].finitime,job[i].reqtime,job[i].TAtime,job[i].TAWtime); 
189         i++;
190     }
191         printf("
平均作业周转时间= %.2lf",sumTA/(i-1));
192         printf("
平均带权作业周转时间= %.2lf",sumTAW/(i-1));
193 }
194 
195 
196 //最短作业优先算法SJF
197 void SJF()
198 {
199     int i=1,j=1;
200     float sumTA=0,sumTAW=0;
201     printf("-----------最短作业优先算法SJF-------------
");
202     printf("
作业名   作业到达时间     作业运行所需要时间
");
203     while(job[j].id!=NULL)
204     {
205         printf("
%3d%12d%15d",job[j].id,job[j].arrtime,job[j].reqtime);  //输出到屏幕
206         jobarr[j]=job[j];
207         j++;
208     }
209     sort(j-1);
210     printf("

作业名   作业到达时间   作业完成时间   运行时间  作业周转时间  带权作业周转时间
");
211     while(jobarr[i].id!=NULL)
212     {
213         if(i==1)
214         {
215             jobarr[i].startime=jobarr[i].arrtime;
216         }
217         else
218         {
219             if(jobarr[i-1].finitime>=jobarr[i].arrtime)
220                 jobarr[i].startime=jobarr[i-1].finitime;
221             else
222                 jobarr[i].startime=jobarr[i].arrtime;
223         }
224         jobarr[i].finitime=jobarr[i].startime+jobarr[i].reqtime;
225         jobarr[i].TAtime=jobarr[i].finitime-jobarr[i].arrtime;
226         jobarr[i].TAWtime=jobarr[i].TAtime/jobarr[i].reqtime;
227         sumTA+=jobarr[i].TAtime;
228         sumTAW+=jobarr[i].TAWtime;
229         printf("
%3d%12d%13d%14d%12.0lf%14.2lf",jobarr[i].id,jobarr[i].arrtime,jobarr[i].finitime,jobarr[i].reqtime,jobarr[i].TAtime,jobarr[i].TAWtime); 
230         i++;
231     }
232         printf("
平均作业周转时间= %.2lf",sumTA/(i-1));
233         printf("
平均带权作业周转时间= %.2lf",sumTAW/(i-1));
234 }
235 
236 
237 //最高响应比排序
238 void sort1(int n,int k)
239 {
240     int i,j; 
241     struct jcb temp;
242     for(i=k;i<n;i++) 
243     for(j=i+1;j<=n;j++) 
244     if(jobfin[i].prio<jobfin[j].prio) 
245     { 
246        temp=jobfin[i]; 
247        jobfin[i]=jobfin[j]; 
248        jobfin[j]=temp; 
249     } 
250 }
251 
252 
253 //响应比最高者优先HRRF算法
254 void HRRF()
255 {
256     int i=1,j=1,k=1;
257     float sumTA=0,sumTAW=0;
258     printf("-----------响应比最高者优先HRRF算法-------------
");
259     printf("
作业名   作业到达时间     作业运行所需要时间
");
260     while(job[j].id!=NULL)
261     {
262         printf("%3d%12d%15d
",job[j].id,job[j].arrtime,job[j].reqtime);  //输出到屏幕
263         jobfin[j]=job[j];
264         j++;
265     }
266     while(jobfin[k].id!=NULL)
267     {
268         i=k;  
269         if(k==1)
270         {
271             jobfin[i].startime=jobfin[i].arrtime;
272             jobfin[i].finitime=jobfin[i].startime+jobfin[i].reqtime;
273             jobfin[i].TAtime=jobfin[i].finitime-jobfin[i].arrtime;
274             jobfin[i].TAWtime=jobfin[i].TAtime/jobfin[i].reqtime;
275         }
276         else
277         {
278         printf("
作业名   最高响应比
");
279         while(jobfin[i].id!=NULL)
280         {
281             if(jobfin[k-1].finitime>=job[i].arrtime)
282             {
283                 jobfin[i].startime=jobfin[k-1].finitime;
284                 jobfin[i].prio=(jobfin[i].startime-jobfin[i].arrtime)/(jobfin[i].reqtime/1.0)+1;
285             }
286             else
287             {
288                 jobfin[i].startime=0;    
289                   jobfin[i].prio=0;
290             }
291             i++;
292         }
293         sort1(j-1,k);
294         for(i=k;i<j;i++)
295             printf("%3d%10.2lf
",jobfin[i].id,jobfin[i].prio);
296         jobfin[k].finitime=jobfin[k-1].finitime+jobfin[k].reqtime;
297         jobfin[k].TAtime=jobfin[k].finitime-jobfin[k].arrtime;
298         jobfin[k].TAWtime=jobfin[k].TAtime/jobfin[k].reqtime;
299         }
300         k++;
301     }
302         printf("

作业名   作业到达时间   作业完成时间   运行时间  作业周转时间  带权作业周转时间
");
303         for(i=1;i<j;i++)
304         {
305             printf("
%3d%12d%13d%14d%12.0lf%14.2lf",jobfin[i].id,jobfin[i].arrtime,jobfin[i].finitime,jobfin[i].reqtime,jobfin[i].TAtime,jobfin[i].TAWtime); 
306             sumTA+=jobfin[i].TAtime;
307             sumTAW+=jobfin[i].TAWtime;
308         }
309         printf("
平均作业周转时间= %.2lf",sumTA/(i-1));
310         printf("
平均带权作业周转时间= %.2lf",sumTAW/(i-1));
311 }
312 
313 
314 void main0()
315 {
316     int tmp;
317     while(1)
318     {
319     menu0();
320     printf("
请选择菜单项:");
321     scanf("%d",&tmp);
322     switch (tmp)
323     {
324     case 1:
325         FCFS();
326         break;
327     case 2:
328         SJF();
329         break;
330     case 3:
331         HRRF();
332         break;
333     case 4:
334         system("cls");
335         break;
336     case 0:
337         return;
338     }
339     }
340 }
341 
342 
343 main()
344 {
345     int tmp;
346     while(1)
347     {
348     menu();
349     printf("
请选择菜单项:");
350     scanf("%d",&tmp);
351     switch (tmp)
352     {
353     case 1:
354         ReadFile();
355         break;
356     case 2:
357         Pseudo_random_number();
358         break;
359     case 3:    
360         shoushu();
361         break;
362     }
363     main0();
364     printf("
");
365     }
366 }

实验结果:

FCFS:

SJF:

HRRF:

实验总结:

      刚开始做这个实验时我觉得很难,有点不知所措,但是通过老师的一些讲解和提供的思路,自己也上网百度了一些不懂的东西,最后成功完成了这个作业调度的一些基本要求,所以我觉得,付出多少,必然有所收获。 

学号:201406114214

                                                                                                                                                                                                姓名:冯梓凡

原文地址:https://www.cnblogs.com/14fzf/p/5420924.html