OS(A)之进程调度模拟算法

Posted ynly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OS(A)之进程调度模拟算法相关的知识,希望对你有一定的参考价值。

进程调度模拟算法

一、实验目的

    进程调度是处理机管理的核心内容。本实验要求用高级语言编写模拟进程调度程序,以便加深理解有关进程控制快、进程队列等概念,并体会和了解优先数算法和时间片轮转算法的具体实施办法。

 

二、实验内容

    1.设计进程控制块PCB 的结构,通常应包括如下信息:

        进程名、进程优先数(或轮转时间片数)、进程已占用的CPU 时间、进程到完成还需要的时间、进程的状态、当前队列指针等。

    2.编写两种调度算法程序:

        优先数调度算法程序

        循环轮转调度算法程序

    3.按要求输出结果。

 

三、实验过程

(一)进程控制块结构如下:

       NAME——进程标示符

       PRIO/ROUND——进程优先数/进程每次轮转的时间片数(设为常数2)

       CPUTIME——进程累计占用CPU 的时间片数

       NEEDTIME——进程到完成还需要的时间片数

       STATE——进程状态

       NEXT——链指针

     注:1. 为了便于处理,程序中进程的的运行时间以时间片为单位进行计算;

            2. 各进程的优先数或轮转时间片数,以及进程运行时间片数的初值,均由用户在程序运行时给定。

(二)进程的就绪态和等待态均为链表结构,共有四个指针如下:

       RUN——当前运行进程指针

       READY——就需队列头指针

       TAIL—— 就需队列尾指针

       FINISH—— 完成队列头指针

(三)程序说明

       1. 在优先数算法中,进程优先数的初值设为:

              50-NEEDTIME每执行一次,优先数减1,CPU 时间片数加1,进程还需要的时间片数减1。

              在轮转法中,采用固定时间片单位(两个时间片为一个单位),进程每轮转一次,CPU时间片数加2,进程还需要的时间片数减2,并退出CPU,排到就绪队列尾,等待下一次调度。

       2. 程序的模块结构提示如下:

              整个程序可由主程序和如下7 个过程组成:

              (1)INSERT1——在优先数算法中,将尚未完成的PCB 按优先数顺序插入到就绪队列中;

              (2)INSERT2——在轮转法中,将执行了一个时间片单位(为2),但尚未完成的进程的PCB,插到就绪队列的队尾;

              (3)FIRSTIN——调度就绪队列的第一个进程投入运行;

              (4)PRINT——显示每执行一次后所有进程的状态及有关信息。

              (5)CREATE——创建新进程,并将它的PCB 插入就绪队列;

              (6)PRISCH——按优先数算法调度进程;

              (7)ROUNDSCH——按时间片轮转法调度进程。

       主程序定义PCB 结构和其他有关变量。

(四)运行和显示

       程序开始运行后,首先提示:请用户选择算法,输入进程名和相应的NEEDTIME 值。

       每次显示结果均为如下5 个字段:

       name cputime needtime priority state

      注: 1.在state 字段中,"R"代表执行态,"W"代表就绪(等待)态,"F"代表完成态。

              2.应先显示"R"态的,再显示"W"态的,再显示"F"态的。

              3.在"W"态中,以优先数高低或轮转顺序排队;在"F"态中,以完成先后顺序排队。

 

四、实验结果

   • 上机调试

 技术图片

 

 技术图片

 

 技术图片

 

 技术图片

 

 技术图片

 

 技术图片

 

 技术图片

 

 技术图片

 

   • 遇到的主要问题和解决方法

        在利用指针处理时很困难,也经历了很艰难的过程,实验中设计了结构指针用来指向PCB结构,PCB结构中又有链表指针。

 

五、实验总结

        通过本次试验对优先数调度算法和时间片轮转调度算法实现的过程,有了很清楚的认识、理解。随后通过设计PCB结构,模拟进程调度,加深了对进程的理解。

 

六、源代码

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 #include<windows.h>
  5 
  6 /*进程控制块数据结构*/
  7 typedef struct node 
  8 {
  9 char name[10];/*进程名*/
 10 int prio;     /*进程优先级*/ 
 11 int round;    /*循环轮转法进程每次轮转的时间片*/ 
 12 int cputime; /*进程累计消耗的CUP时间*/
 13 int needtime; /*进程到完成还需要的CUP时间*/
 14 int count;    /*循环轮转法一个是时间片内进程运行时间*/
 15 char state;   /*进程的状态:‘R‘:运行,‘W‘:等待,‘F‘:结束*/
 16 struct node *next;/*指向下一个进程的链指针*/     
 17 }PCB;
 18 
 19 PCB *finish,*ready,*tail,*run;/*指向三个队列的队首的指针,
 20                                 finish为完成队列头指针,
 21                                 ready为就绪队列头指针,                                
 22                                 tail为就绪队列的队尾指针,
 23                                 run为当前运行进程头指针*/
 24 
 25 int N;/*定义进程的数目*/
 26 
 27 
 28 void firstin(void);                //调度就绪队列的第一个进程投入运行;
 29  void print1(char a);            //打印表头行信息
 30 void print2(char chose,PCB *p);    //打印每一行的状态信息
 31 void print(char chose);            //打印每执行一次算法后所有的进程的状态信息
 32 void insert_prio(PCB *q);        //在优先数算法中,将尚未完成的PCB按优先数顺序插入到就绪队列中;        
 33 void prior_init(char chose);    //进程优先级法初始化将进程按优先级插入到就绪队列里                                
 34 void priority(char chose);        //进程优先级算法总函数
 35 void insert_rr(PCB *q);            //在轮转法中,将执行了一个时间片单位(为2),但尚未完成的进程的PCB,插到就绪队列的队尾;                                
 36 void roundrun_init(char chose);    //循环轮转法初始化将就绪队列保存为FIFO队列                                
 37 void roundrun(char chose);        //循环轮转法总算法
 38 
 39 
 40 
 41 
 42 
 43 void main()//主函数
 44 {
 45         char chose= ;
 46         while((chose!=q)&&(chose!=Q))
 47     {
 48             fflush(stdin);
 49             printf("选择进程优先级算法请输入P,选择循环轮转算法请输入R,退出请输入Q
");
 50             printf("请输入你的选择:");
 51             scanf("%c",&chose);
 52             if((chose!=q)&&(chose!=Q))
 53         {
 54                 system("cls");
 55                 if((chose==P)||(chose==p))
 56             {
 57                     
 58                     prior_init(chose);
 59                     priority(chose);
 60                     system("cls");
 61             } 
 62    
 63                 else if((chose==r)||(chose==R))
 64             {
 65                             
 66                     roundrun_init(chose);
 67                     roundrun(chose);
 68                     system("cls");
 69    
 70             }
 71         }
 72     }
 73         printf("谢谢使用!
");
 74 }
 75 
 76 void firstin(void)//调度就绪队列的第一个进程投入运行;
 77 {
 78     if(ready!=NULL)
 79     {
 80      run=ready;
 81      ready=ready->next;
 82      run->state=R;
 83      run->next=NULL;
 84    }
 85    else
 86    {
 87      run=NULL;
 88      
 89    }
 90    
 91 }
 92 
 93 
 94 
 95 
 96 
 97 
 98 
 99 
100 void print1(char a)//打印表头行信息
101 {
102 if(toupper(a)==P)
103 {
104 printf("name  cputime  needtime priority state 
");
105 }
106 else
107 {
108 printf("name  cputime  needtime count round state 
"); 
109 }    
110 }
111 
112 
113 
114 
115 
116 
117 
118 
119 void print2(char chose,PCB *p)//打印每一行的状态信息
120 {
121 if(toupper(chose)==P)
122 {
123    printf("%s	%d	%d	%d	%c
",p->name,p->cputime,p->needtime,p->prio,p->state);
124    
125 }
126 else
127 {
128 printf("%s	%d	%d	%d	%d	%c
",p->name,p->cputime,p->needtime,p->count,p->round,p->state);
129 }
130 }
131 void print(char chose)//打印每执行一次算法后所有的进程的状态信息
132 {
133 PCB *p;
134 print1(chose);
135 if(run!=NULL)
136 {
137 print2(chose,run);
138 }
139 
140 p=ready;
141 while(p!=NULL)
142 {
143    print2(chose,p);
144    p=p->next;
145 }
146 
147 p=finish;
148 while(p!=NULL)
149 {
150 print2(chose,p);
151 p=p->next;
152 }
153 
154 }
155 void insert_prio(PCB *q)/*在优先数算法中,将尚未
156                         完成的PCB按优先数顺序插入到就绪队列中;*/
157 {
158 PCB *p,*s,*r; /*p,r用来控制就绪队列滚动,S指向插入的队列*/
159  
160 s=q;
161 p=ready;
162 r=p;
163 
164 if(s->prio>ready->prio)// 要插入的进程的优先级大于ready的优先级
165 {
166    s->next=ready;
167 ready=s;          
168 }
169 else//要插入的进程的优先级不大于ready的优先级
170 {
171    while(p)
172    {
173         if(p->prio>=s->prio)
174     {
175         r=p;
176         p=p->next;
177     }
178         else
179             break;
180     
181    } //找到要插入的位置
182 s->next=p;
183 r->next=s;
184 }
185 }
186 
187 
188 
189 void prior_init(char chose)/*进程优先级法初始化
190                         将进程按优先级插入到就绪队列里*/
191 {
192             PCB *p;
193             int i,time;
194             char na[10];
195             ready=NULL;
196             finish=NULL;
197             run=NULL;
198             printf("输入进程 的个数 N:
");
199             scanf("%d",&N);
200 for(i=0;i<N;i++)
201 {
202 p=(PCB*)malloc(sizeof(PCB));
203    printf("输入第%d个进程名
",i+1);
204 scanf("%s",na);
205    printf("完成进程需要的时间片数
");
206 scanf("%d",&time);
207 strcpy(p->name,na);
208 p->cputime=0;
209 p->needtime=time;
210 p->state=W;
211 p->prio=50-time;//设置进程优先值初值
212 
213 if(ready==NULL)
214 {
215    ready=p;
216    ready->next=NULL;
217 }
218 else
219 {
220     insert_prio(p);
221 }
222 printf("当前就绪队列的进程的信息
");
223 print(chose);
224 }
225 printf("%d个进程已按优先级从高到低进到就绪队列中
",N);
226                     printf("按回车键开始模拟优先级算法.....
");
227                     fflush(stdin);
228                     getchar();
229 firstin();
230 }
231 void priority(char chose)//进程优先级算法总函数
232 {
233     int i=1;
234 
235 while(run!=NULL)
236 {
237     run->cputime+=1;
238     run->needtime-=1;
239     run->prio-=1;
240 if(run->needtime==0)
241 {
242       run->next=finish;
243       finish=run;
244       run->state=F;
245       run->prio=0;
246       run=NULL;
247       firstin();        
248 }
249 else
250 {
251      if((ready!=NULL)&&(run->prio<ready->prio))
252      {
253         run->state=W;
254         insert_prio(run);
255         run=NULL;
256         firstin();
257      }
258 }
259 
260 
261    print(chose);
262    
263    
264 }
265 
266 getchar();
267 }
268 void insert_rr(PCB *q)//在轮转法中,将执行了一个时间片单位(为2),
269                     //但尚未完成的进程的PCB,插到就绪队列的队尾;
270 {
271     tail->next=q;
272     tail=q;
273     q->next=NULL;
274 }
275 void roundrun_init(char chose)/*循环轮转法初始化
276                               将就绪队列保存为FIFO队列*/
277 {
278 PCB *p;
279 int i,time;
280 char na[10];
281 ready=NULL;
282 finish=NULL;
283 run=NULL;
284     printf("		循环轮转算法模拟全过程

");
285                     printf("输入进程 的个数 N:
");
286                     scanf("%d",&N);
287 for(i=0;i<N;i++)
288 {
289 p=(PCB*)malloc(sizeof(PCB));
290    printf("输入第%d个进程名
",i+1);
291 scanf("%s",na);
292    printf("完成进程需要的时间片数
");
293 scanf("%d",&time);
294 strcpy(p->name,na);
295 p->cputime=0;
296 p->needtime=time;
297 p->count=0;
298 p->state=W;
299 p->round=2;
300 if(ready!=NULL)
301 {
302 insert_rr(p);
303 }
304 else
305 {
306     p->next=ready;
307     ready=p;
308     tail=p;
309 }
310 printf("当前就绪队列的进程的信息
");
311 print(chose);
312 }
313     printf("%d个进程已按FIFO进到就绪队列中
",N);
314                     printf("按回车键开始模循环轮转算法.....
");
315                     fflush(stdin);
316                     getchar();
317 run=ready;
318 ready=ready->next;
319 run->state=R;
320      
321 }
322 void roundrun(char chose)//循环轮转法总算法
323 {
324     int i=1;
325 while(run!=NULL)
326 {
327 run->cputime+=1;
328 run->needtime-=1;
329 run->count+=1;
330 if(run->needtime==0)
331 {
332     run->next=finish;
333    finish=run;
334    run->state=F;
335    run->prio=0;
336    run=NULL;
337    if(ready!=NULL)
338    {
339       firstin();
340     }         
341    }
342    else
343    {
344      if(run->count==run->round)
345      {
346      run->count=0; 
347      if(ready!=NULL)
348    {        
349       run->state=W;
350       insert_rr(run);
351       firstin();
352    }
353     }
354    }
355   
356    print(chose);
357    
358    
359 }
360 getchar();
361 
362 }

 

以上是关于OS(A)之进程调度模拟算法的主要内容,如果未能解决你的问题,请参考以下文章

操作系统实验—处理机调度算法的模拟

操作系统实验二(调度算法模拟-先进先出-时间片轮转法-优先服务调度算法)

向题看齐408之操作系统OS概念记忆总结

向题看齐408之操作系统OS概念记忆总结

向题看齐408之操作系统OS概念记忆总结

模拟处理机进程调度-简单循环轮转调度算法