39 进程调度实验

一、 实验目的

1.用高级语言完成一个进程调度程序,以加深对进程的概念及进程调度算法的理解。

2.实验要求

3.设计一个有 N(N不小于5)个进程并发执行的进程调度模拟程序。

4.进程调度算法:“时间片轮转法”调度算法对N个进程进行调度。

 

二、 实验内容和要求

完成两个算法(简单时间片轮转法、多级反馈队列调度算法)的设计、编码和调试工作,完成实验报告。

1) 每个进程有一个进程控制块(PCB)表示。进程控制块包含如下信息:进程名、优先级、到达时间、需要运行时间、已用CPU时间、进程状态等等。 

2) 每个进程的状态可以是就绪 r(ready)、运行R(Running)、或完成F(Finished)三种状态之一。

3) 就绪进程获得 CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。

4) 如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,应把它插入就绪队列等待下一次调度。

5) 每进行一次调度,程序都打印一次运行进程、就绪队列中各个进程的 PCB,以便进行检查。   

6) 重复以上过程,直到所要进程都完成为止。

 

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

1.源程序名:1125.c

可执行程序名:1125.exe

2.原理分析及流程图

1)理解简单轮转法与多级反馈队列调度算法;

2)流程图:

3.主要程序段及其解释:

  1 #include<stdio.h>
  2 
  3 #define MAX 24 
  4 
  5 typedef struct node
  6 {
  7     char name[10];//作业名
  8     int arrivetime;//作业到达时间
  9     int runtime;//作业所需的运行时间
 10     int usetime; //已用CPU时间 
 11     char stage; //进程的状态 
 12     int starttime; //开始时间
 13     int endtime; //结束时间 
 14     int zztime; //作业周转时间
 15     float zzxs; //周转系数 
 16 }JCB;
 17 
 18 static unsigned int N=5;  //作业数
 19 static int current=0, current1=0;  //当前时间
 20 static unsigned int j=-1, j1=-1; 
 21 JCB job[MAX];
 22 
 23 void Line();
 24 void FCFS();
 25 void getValue();
 26 void getValue1();
 27 void input();
 28 void print();
 29 void choice();
 30 void SJF();
 31 
 32 void getValue() 
 33 {
 34     unsigned int i;
 35     current=job[0].arrivetime;
 36     for(i=0; i<N; i++)   
 37     {
 38         if(job[i].stage=='r' && current>=job[i].arrivetime)
 39         {
 40             if(job[i].usetime==0)
 41                 job[i].starttime=current;
 42             job[i].stage='R';   //程序正在运行 
 43             job[i].usetime++;  //CPU的运行时间加1
 44             current++;
 45         }
 46         if(job[i].usetime==job[i].runtime && job[i].stage=='R')
 47         {
 48             j++;          //用来标记有多少进程完成了
 49             job[i].stage='F';
 50             job[i].endtime=current;
 51             job[i].zztime=job[i].endtime-job[i].arrivetime;
 52             job[i].zzxs=(float)job[i].zztime/(float)job[i].runtime;
 53         }
 54         if(job[i].stage!='F')
 55             job[i].stage='r';  //运行完之后变回就绪态 
 56         if(i==N-1)   //进入死循环了
 57             i=-1;
 58         if(j==N-1)
 59             break;
 60     }
 61 }
 62 
 63 void getValue1() 
 64 {
 65     unsigned int i=0, h, rest;
 66     current1=job[0].arrivetime;
 67     for(; i<N; i++)   
 68     {
 69         if(job[i].stage=='2')
 70         {
 71             h=0;
 72             while(h<N)     //判断当前时刻的这一级是否有进程
 73             {
 74                 if(job[h].stage=='r' && current1>=job[h].arrivetime)
 75                 {    
 76                     i=h;
 77                     h=N;
 78                 }
 79                 h++;
 80             }
 81         }
 82         else if(job[i].stage=='3')
 83         {
 84             h=0;
 85             while(h<N)     //判断当前时刻的这一级是否有进程
 86             {
 87                 if(job[h].stage=='2')
 88                 {    
 89                     i=h;
 90                     h=N;
 91                 }
 92                 h++;
 93             }
 94         }
 95         if(job[i].stage=='r' && current1>=job[i].arrivetime)      
 96         {
 97             if(job[i].usetime==0)
 98                 job[i].starttime=current1;
 99             job[i].stage='R';   //程序正在运行 
100             job[i].usetime++;  //CPU的运行时间加1
101             current1++;
102             if(job[i].usetime==job[i].runtime)
103             {
104                 j1++;
105                 job[i].stage='F';
106                 job[i].endtime=current1;
107                 job[i].zztime=job[i].endtime-job[i].arrivetime;
108                 job[i].zzxs=(float)job[i].zztime/(float)job[i].runtime;
109             }
110             else    //还没完成则进入下一级
111                 job[i].stage='2';
112         }
113         else if(job[i].stage=='2')
114         {
115             job[i].stage='R';
116             job[i].usetime+=2;
117             current1+=2;
118             if(job[i].usetime>=job[i].runtime)
119             {
120                 j1++;
121                 job[i].stage='F';
122                 rest=job[i].usetime-job[i].runtime;
123                 current1=current1-rest;
124                 job[i].endtime=current1;
125                 job[i].zztime=job[i].endtime-job[i].arrivetime;
126                 job[i].zzxs=(float)job[i].zztime/(float)job[i].runtime;
127             }
128             else    //还没完成则进入下一级
129                 job[i].stage='3';
130         }
131         else if(job[i].stage=='3')
132         {
133             job[i].stage='R';
134             job[i].usetime+=4;
135             current1+=4;
136             if(job[i].usetime>=job[i].runtime)
137             {
138                 j1++;
139                 job[i].stage='F';
140                 rest=job[i].usetime-job[i].runtime;
141                 current1=current1-rest;
142                 job[i].endtime=current1;
143                 job[i].zztime=job[i].endtime-job[i].arrivetime;
144                 job[i].zzxs=(float)job[i].zztime/(float)job[i].runtime;
145             }
146             else    //还没完成则在最后一级继续轮转
147                 job[i].stage='3';
148         }
149         if(i==N-1)   //进入死循环了
150             i=-1;
151         if(j1==N-1)
152             break;
153     }
154 }
155 
156 void input()
157 {
158     int i, jobNum, choi;
159     printf("1.自选作业个数
");
160     printf("2.系统默认作业个数
");
161     printf("你的选择是:");
162     scanf("%d", &choi);
163     switch(choi)
164     {
165     case 1:
166         {
167             do{
168                 printf("
Enter process number(作业个数应在2~24之间):");
169                 scanf("%d", &jobNum);   //输入作业数 
170                 N=jobNum;
171                 printf("
");
172             }while(N<2 || N>24);
173             break;
174         }    
175     case 2:
176         printf("
系统默认作业个数为5");
177         break;
178     }
179     for(i=0; i<jobNum; i++)
180     {
181         printf("
job %d name:",i+1);
182         scanf(" ");
183         gets(job[i].name);    //输入作业名 
184         printf("arrive time:");
185         scanf(" %d",&job[i].arrivetime);    //输入作业达到时间 
186         printf("running time:");
187         scanf(" %d",&job[i].runtime);    //输入作业执行时间 
188     }
189 }
190 
191 void print()
192 {
193     unsigned int i;
194     printf("     name  arrivetime  runtime  starttime  endtime  zztime  zzxs
");    
195     for(i=0; i<N; i++)
196     {
197         printf("jod%d",i+1);
198         printf("  %s		%d         %d         %d         %d        %d     %.2f
",job[i].name,job[i].arrivetime,job[i].runtime,job[i].starttime,job[i].endtime,job[i].zztime,job[i].zzxs);
199     }
200 }
201 void choice()
202 {
203     int mark;
204     do{
205         printf("

1. 简单轮转法;
2. 多级反馈队列调度算法;
3. 退出.");
206         printf("
Make choice: ");
207         scanf("%d", &mark);
208         switch(mark)
209         {
210             case 1:
211                 FCFS();     //简单轮转法
212
break; 213 case 2: 214 SJF(); //多级反馈队列调度算法
215 break; 216 case 3: 217 return; 218 default: 219 printf(" error!"); 220 } 221 }while(mark!=3); 222 } 223 224 void Line() 225 { 226 unsigned int a, b; 227 JCB mark; 228 current=0; current1=0; 229 j=-1; j1=-1; 230 for(a=0; a<N; a++) 231 { 232 job[a].usetime=0; 233 job[a].stage='r'; //就绪态 234 job[a].starttime=0; 235 job[a].endtime=0; 236 job[a].zztime=0; 237 job[a].zzxs=0; 238 } 239 for(a=0;a<N-1; a++) //通过到达时间整体排序 240 { 241 for(b=a+1; b<N; b++) 242 { 243 if(job[b].arrivetime<job[a].arrivetime) 244 { 245 mark=job[b]; 246 job[b]=job[a]; 247 job[a]=mark; 248 } 249 } 250 } 251 } 252 253 void FCFS() 254 { 255 Line(); 256 getValue(); //给每个作业内的相关参数赋值 257 print(); //打印出来 258 } 259 260 void SJF() 261 { 262 Line(); 263 getValue1(); 264 print(); //打印出来 265 } 266 267 void main() 268 { 269 input(); //输入 270 print(); //打印输出 271 choice(); //选择方式 272 }

4.运行结果及分析

 

图4.1 提示用户输入信息

图4.2 简单轮转法结果

图4.3 多级反馈队列调度算法结果

 

四、 实验总结

     在前一次作业调度程序的基础上,改进成进程调度其实并不难,因为有那样的思维在里面,但是在做这次实验的过程中,首先理解简单轮转法和多级反馈跳读算法是很关键的,理解后顺着算法的思路编程,即使出现问题了,也能很快的找到是哪里的问题,并且不断地调试、改正,最后得到结果。

原文地址:https://www.cnblogs.com/1994-ann/p/5020897.html