【操作系统】实验二 作业调度模拟程序

实验一、作业调度模拟程序实验

商业软件工程   杨晶晶  201406114102

一、        实验目的

(1)加深对作业调度算法的理解;

(2)进行程序设计的训练。

二、        实验内容和要求

实验内容

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

实验要求

用高级语言编写一个或多个作业调度的模拟程序。

单道批处理系统的作业调度程序。作业一投入运行,它就占有计算机的一切资源直到作业完成为止,因此调度作业时不必考虑它所需要的资源是否得到满足,它所运行的时间等因素。

 

一、       模拟数据的生成

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

为了方便模拟调度过程,作业使用什么方式的数据结构存放和表示?

由作业说明书在系统中生成一个称为作业控制块(job control block,JCB)的表格。该表格登记该作业所要求的资源情况、预计执行时间和执行优先级等。从而,操作系统通过该表了解到作业要求,并分配资源和控制作业中程序和数据的编译、链接、装入和执行等。

4

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

先来先服务算法、最短作业优先算法、最短剩余时间优先算法、最高响应比优先算法、轮转调度算法、多级反馈队列调度算法、优先级法调度算法  

5

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

 

6

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

 

 

五、       其他要求

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

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

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

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

     单道FCFS算法:

        

 

三、        实验方法、步骤及结果测试

 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.      运行结果及分析

四、        实验总结

这次的实验做的时间挺长的,主要实现了三种作业调度算法,还可以通过产生随机数来产生数据。一开始的代码都写在main函数里面,看起来不美观而且不方便,所以把代码都分开放到不同的方法里面,改起来会比较方便。在实现最短作业优先算法的时候一开始忽略了第一个作业是最先到达,而且只有一个作业在调度,不管其他的作业时间有多短都应该先运行作业一。在实现最高响应比优先算法的时候,虽然知道怎么比较计算响应比,可是不太会实现算法让他们进行作业调度,后来向同学求助还有上网参考一些代码实现。这过程有很多粗心的地方,比如计算公式错了,本来是整形,输出却打印浮点型的数,弄得一直是显示0。以后要多练习多注意细节问题。

 

 

 

 

 

 

 

 

posted @ 2016-04-15 11:15  02杨晶晶  阅读(1505)  评论(0编辑  收藏  举报