码迷,mamicode.com
首页 > 编程语言 > 详细

操作系统,时间片轮转算法的C语言实现Round Robin

时间:2018-11-20 21:46:45      阅读:226      评论:0      收藏:0      [点我收藏+]

标签:float   read   etc   play   控制   pre   返回   and   star   

  1 #include "windows.h"
  2 #include <conio.h>
  3 #include <stdlib.h>
  4 #include <fstream.h>
  5 #include <io.h>
  6 #include <string.h>
  7 #include <stdio.h>
  8 
  9 void Create_ProcInfo(); // 建立进程调度需要的数据
 10 void Display_ProcInfo();   // 显示当前系统全部进程的状态
 11 void Scheduler_FF();
 12 void Cpu_Sched();
 13 void IO_Sched();
 14 void NextRunProcess();
 15 void DisData();
 16 void DisResult();
 17 
 18 int   RunPoint;   // 运行进程指针,-1时为没有运行进程
 19 int   WaitPoint;  // 阻塞队列指针,-1时为没有阻塞进程
 20 int   ReadyPoint; // 就绪队列指针,-1时为没有就绪进程
 21 long  ClockNumber;   // 系统时钟
 22 int   ProcNumber;    // 系统中模拟产生的进程总数
 23 int   FinishedProc;    // 系统中模拟产生的进程总数
 24 int q=9;//时间片
 25 
 26 
 27 //进程信息结构
 28 struct ProcStruct  
 29 {
 30     int  p_pid;         // 进程的标识号
 31     char p_state;       // 进程的状态,C--运行  R--就绪  W--组塞  B--后备  F--完成
 32     int  p_rserial[16]; // 模拟的进程执行的CPU和I/O时间数据序列,间隔存储,0项存储有效项数
 33     int  p_pos;         // 当前进程运行到的序列位置
 34     int  p_starttime;   // 进程建立时间
 35     int  p_endtime;     // 进程运行结束时间
 36     int  p_cputime;     // 当前运行时间段进程剩余的需要运行时间
 37     int  p_iotime;      // 当前I/O时间段进程剩余的I/O时间
 38     int  p_next;        // 进程控制块的链接指针
 39     int  p_excutetime;  // 记录一次时间片内执行的时间
 40 } proc[10];
 41 
 42 ////////////////////////////////////////////////////////////////////////////
 43 //
 44 //  随机生成进程数量和每个CPU--I/O时间数据序列,进程数量控制在5到10之间, //
 45 //  数据序列控制在6到12之间,CPU和I/O的时间数据值在5到15的范围           //
 46 //
 47 ////////////////////////////////////////////////////////////////////////////
 48 
 49 void Create_ProcInfo(void )
 50 {
 51     int s,i,j;
 52     
 53     srand(GetTickCount());                        // 初始化随机数队列的"种子"
 54     ProcNumber=((float) rand() / 32767) * 5 ;  // 随机产生进程数量5~10
 55 
 56     
 57     for(i=0;i<ProcNumber;i++)    // 生成进程的CPU--I/O时间数据序列
 58     {  
 59         proc[i].p_pid=((float) rand() / 32767) * 1000;
 60         proc[i].p_state=B;   // 初始都为后备状态
 61         
 62         s=((float) rand() / 32767) *6 + 2; // 产生的进程数据序列长度在6~12间
 63         proc[i].p_rserial[0]=s; // 第一项用于记录序列的长度
 64         for(j=1;j<=s;j++)  // 生成时间数据序列
 65             proc[i].p_rserial[j]=((float) rand() / 32767) *10 + 5;
 66         // 赋其他字段的值
 67         proc[i].p_pos=1;
 68         proc[i].p_starttime=((float) rand() / 32767) *49+1;   // 随机设定进程建立时间
 69         proc[i].p_endtime=0;    
 70         proc[i].p_cputime=proc[i].p_rserial[1];  
 71         proc[i].p_iotime=proc[i].p_rserial[2];  
 72         proc[i].p_next=-1; 
 73         proc[i].p_excutetime=0;
 74     }     
 75     printf("\n---------------------------\n    建立了%2d 个进程数据序列\n\n", ProcNumber);
 76     DisData();
 77     printf("\nPress Any Key To Continue.......");
 78     _getch() ; 
 79     return ;
 80 }
 81 
 82 ////////////////////////////////////////////////////////////////////////
 83 
 84 //                        显示系统当前状态
 85 
 86 ////////////////////////////////////////////////////////////////////////
 87 
 88 void Display_ProcInfo(void)
 89 {  int i,n;
 90 
 91 system("cls") ;
 92 printf("时间片为%d",q);
 93 printf("\n        当前系统模拟%2d 个进程的运行    时钟:%ld\n\n", ProcNumber,ClockNumber);
 94 
 95 printf("        就绪指针=%d, 运行指针=%d, 阻塞指针=%d\n\n",ReadyPoint,RunPoint,WaitPoint );
 96 if(RunPoint!= -1)
 97 {
 98        printf(" 当前运行的进程   No.%d ID:%d\n", RunPoint,proc[RunPoint].p_pid);
 99        printf("              %6d,%6d,%6d\n",proc[RunPoint].p_starttime,proc[RunPoint].p_rserial[proc[RunPoint].p_pos],proc[RunPoint].p_cputime);
100        printf("当前运行的进程执行的时间为%d",proc[RunPoint].p_excutetime);
101        printf("当前运行的进程执行的cpu时间为%d",proc[RunPoint].p_cputime);
102 }
103 else
104 printf(" 当前运行的进程ID:No Process Running !\n");
105 
106 n=ReadyPoint;
107 printf("\n Ready Process ...... \n");
108 while(n!=-1) // 显示就绪进程信息
109 {   
110        printf("     No.%d ID:%5d,%6d,%6d,%6d\n",n,proc[n].p_pid,proc[n].p_starttime,proc[n].p_rserial[proc[n].p_pos],proc[n].p_cputime );
111        n=proc[n].p_next;
112 }
113 
114 n=WaitPoint;
115 printf("\n Waiting Process ...... \n");
116 while(n!=-1) // 显示阻塞进程信息
117 {   
118        printf("     No.%d ID:%5d,%6d,%6d,%6d\n",n,proc[n].p_pid,proc[n].p_starttime,proc[n].p_rserial[proc[n].p_pos],proc[n].p_iotime);
119        n=proc[n].p_next;
120 }
121 
122 printf("\n=================== 后备进程 ====================\n");
123 for(i=0; i<ProcNumber; i++) 
124 if (proc[i].p_state==B)
125 printf("     No.%d ID:%5d,%6d\n",i,proc[i].p_pid,proc[i].p_starttime); 
126 
127 printf("\n================ 已经完成的进程 =================\n");
128 for(i=0; i<ProcNumber; i++) 
129 if (proc[i].p_state==F)
130 printf("No.%d ID:%5d,%6d,%6d\n",i,proc[i].p_pid,proc[i].p_starttime,proc[i].p_endtime);
131 
132 }
133 
134 ////////////////////////////////////////////////////////////////////////
135 
136 //              显示模拟执行的结果
137 
138 ////////////////////////////////////////////////////////////////////////
139 void DisResult(void)
140 {  int i;   
141 printf("\n---------------------------------\n");
142 for(i=0; i<ProcNumber; i++) 
143 {  
144     printf("ID=%4d> %2d ",proc[i].p_pid ,proc[i].p_rserial[0] );
145     printf("%4d,%4d",proc[i].p_starttime,proc[i].p_endtime);
146     printf("\n" );
147 }  
148 }
149 
150 ////////////////////////////////////////////////////////////////////////
151 
152 //              显示进程数据序列
153 
154 ////////////////////////////////////////////////////////////////////////
155 void DisData(void)
156 {  int i,j;   
157 
158 for(i=0; i<ProcNumber; i++) 
159 {  
160     printf("ID=%4d %2d > ",proc[i].p_pid ,proc[i].p_rserial[0] );
161     for(j=1; j<=proc[i].p_rserial[0];j++)
162         printf("%4d",proc[i].p_rserial[j]);
163     printf("\n" );
164 }  
165 }
166 ////////////////////////////////////////////////////////////////////////
167 
168 //              选择下一个可以运行的进程
169 
170 ////////////////////////////////////////////////////////////////////////
171 void NextRunProcess(void)
172 {
173     if (ReadyPoint==-1) { RunPoint = -1; return;}  // 就绪队列也没有等待的进程
174     
175        proc[ReadyPoint].p_state =C;     //ReadyPoint所指示的进程状态变为执行状态  
176        RunPoint=ReadyPoint;       
177        if( proc[ReadyPoint].p_excutetime==-1)//进程为执行成功,接着上次的cpu时间执行
178        {
179             proc[ReadyPoint].p_excutetime=0;
180        }
181        else
182        proc[ReadyPoint].p_cputime =proc[ReadyPoint].p_rserial[proc[ReadyPoint].p_pos] ;       
183        ReadyPoint=proc[ReadyPoint].p_next;
184        proc[RunPoint].p_next = -1;
185        
186 }
187 ////////////////////////////////////////////////////////////////////////
188 
189 //              CPU调度
190 
191 ////////////////////////////////////////////////////////////////////////
192 
193 void Cpu_Sched(void)
194 { 
195     int n;
196     
197     if (RunPoint == -1)    // 没有进程在CPU上执行
198     {         NextRunProcess();    return;     }
199     
200     proc[RunPoint].p_cputime--;      // 进程CPU执行时间减少1个时钟单位
201     proc[RunPoint].p_excutetime++;
202     if((proc[RunPoint].p_cputime == 0&&proc[RunPoint].p_excutetime<=q))//若时间片未完,但进程已经结束
203     {
204         //printf("若时间片未完,但进程已经结束\n");
205         proc[RunPoint].p_excutetime=0;//清空运行时间
206         // 进程完成本次CPU后的处理
207         if (proc[RunPoint].p_rserial[0]==proc[RunPoint].p_pos) //进程全部序列执行完成
208         {  
209             FinishedProc++;
210             proc[RunPoint].p_state =F;
211             proc[RunPoint].p_endtime = ClockNumber;    
212             RunPoint=-1;  //无进程执行  
213             NextRunProcess(); 
214         }    
215         else //进行IO操作,进入阻塞队列
216         {
217             proc[RunPoint].p_pos++;
218             proc[RunPoint].p_state =W;
219             proc[RunPoint].p_iotime =proc[RunPoint].p_rserial[proc[RunPoint].p_pos];
220             printf("进入阻塞队列\n");
221             n=WaitPoint;
222             if(n == -1) //是阻塞队列第一个I/O进程
223                 WaitPoint=RunPoint; 
224             else
225             {    do //放入阻塞队列第尾
226             {
227                 if(proc[n].p_next == -1) 
228                 { proc[n].p_next = RunPoint;                  
229                 break;
230                 }
231                 n=proc[n].p_next;
232             } while(n!=-1) ;
233             }
234             RunPoint=-1;   
235             NextRunProcess(); 
236         }
237         return;
238     }
239     if(proc[RunPoint].p_cputime > 0&&proc[RunPoint].p_excutetime<q)//时间片未完 程序未执行结束 继续执行
240     {
241         //printf("时间片未完 程序未执行结束 继续执行\n");
242         return;
243     }
244     //{ printf("\n RunPoint=%d,ctime=%d",RunPoint,proc[RunPoint].p_cputime);getchar();return; }
245     if(proc[RunPoint].p_cputime > 0&&proc[RunPoint].p_excutetime==q)//时间片完,但是程序未执行完 放到就绪队列尾部
246     {
247         //printf("时间片完,但是程序未执行完 放到就绪队列尾部\n");
248         int n;  
249         proc[RunPoint].p_state=R;     //    进程状态修改为就绪            
250         proc[RunPoint].p_next=-1;
251         proc[RunPoint].p_excutetime=-1;//清空运行时间,-1代表程序未执行完成
252         if(ReadyPoint==-1) // 就绪队列无进程
253             ReadyPoint=RunPoint;
254         else      // 就绪队列有进程,放入队列尾
255         {     
256             n=ReadyPoint;               
257             while(proc[n].p_next!=-1) n=proc[n].p_next;
258             proc[n].p_next=RunPoint;
259         }
260         RunPoint=-1;
261         NextRunProcess(); //执行下一个进程
262     }
263 
264 }
265 
266 
267 
268 ////////////////////////////////////////////////////////////////////////
269 
270 //              I/O调度
271 
272 ////////////////////////////////////////////////////////////////////////
273 
274 void IO_Sched(void)
275 { 
276     int n,bk;
277     
278     if (WaitPoint==-1) return;   // 没有等待I/O的进程,直接返回
279     
280     proc[WaitPoint].p_iotime--;  // 进行1个时钟的I/O时间 
281     
282     if (proc[WaitPoint].p_iotime > 0) return; // 还没有完成本次I/O
283     
284     // 进程的I/O完成处理
285     if (proc[WaitPoint].p_rserial[0]==proc[WaitPoint].p_pos) //进程全部任务执行完成
286     {  
287         FinishedProc++;
288         proc[WaitPoint].p_endtime = ClockNumber;
289         proc[WaitPoint].p_state =F;    
290         
291         if(proc[WaitPoint].p_next==-1)
292         { WaitPoint=-1;return ;}
293         else //调度下一个进程进行I/O操作
294         {
295             n=proc[WaitPoint].p_next;
296             proc[WaitPoint].p_next=-1;
297             WaitPoint=n;
298             proc[WaitPoint].p_iotime =proc[WaitPoint].p_rserial[proc[WaitPoint].p_pos] ;
299             return ;
300         }    
301     }
302     else //进行下次CPU操作,进就绪队列
303     {        
304         bk=WaitPoint;
305         WaitPoint=proc[WaitPoint].p_next;
306         
307         proc[bk].p_pos++;
308         proc[bk].p_state =R; //进程状态为就绪
309         proc[bk].p_cputime = proc[bk].p_rserial[proc[bk].p_pos];
310         proc[bk].p_next =-1;
311         
312         n=ReadyPoint;   
313         if(n == -1) //是就绪队列的第一个进程
314         {  ReadyPoint=bk;    return;    } 
315         else
316         {  do 
317         {
318             if(proc[n].p_next == -1) { proc[n].p_next = bk;  break ; }
319             n=proc[n].p_next;
320         }
321         while(n!=-1); 
322         }
323     }
324     return ;
325 }
326 
327 
328 
329 
330 
331 ////////////////////////////////////////////////////////////////////////
332 
333 //              检查是否有新进程到达,有则放入就绪队列
334 
335 ////////////////////////////////////////////////////////////////////////
336 
337 void NewReadyProc(void)
338 { 
339     int i,n;
340     
341     for(i=0; i<ProcNumber; i++) 
342     {    
343         if (proc[i].p_starttime == ClockNumber) // 进程进入时间达到系统时间
344         {   
345             proc[i].p_state=R;     //    进程状态修改为就绪            
346             proc[i].p_next=-1;
347             
348             if(ReadyPoint==-1) // 就绪队列无进程
349                 ReadyPoint=i;
350             else      // 就绪队列有进程,放入队列尾
351             {     
352                 n=ReadyPoint;               
353                 while(proc[n].p_next!=-1) n=proc[n].p_next;
354                 proc[n].p_next=i;
355             }
356         }
357     } // for
358     return;       
359 }
360 
361 
362 ////////////////////////////////////////////////////////////////////////
363 
364 //                         调度模拟算法
365 
366 ////////////////////////////////////////////////////////////////////////
367 
368 void Scheduler_FF(void)
369 {
370     FinishedProc=0;
371     if(ProcNumber==0)
372     { printf("    必须首先建立进程调度数据 !  \n");
373     system("cls");    return;
374     }
375     
376     ClockNumber=0;// 时钟开始计时, 开始调度模拟
377     while(FinishedProc < ProcNumber) // 执行算法
378     {     
379         ClockNumber++;  // 时钟前进1个单位
380         NewReadyProc(); // 判别新进程是否到达
381         Cpu_Sched();    // CPU调度
382         IO_Sched();     // IO调度      
383         Display_ProcInfo(); //显示当前状态
384     }
385     DisResult(); 
386     getch();   return;
387 }
388 
389 void Change_q(void)
390 {
391   scanf("%d",&q);
392 }
393 
394 ///////////////////////////////////////////////////////////////////
395 
396 //                          主函数
397 
398 ///////////////////////////////////////////////////////////////////
399 
400 int main(int argc, char* argv[])
401 {
402     char ch;
403     
404     RunPoint=-1;   // 运行进程指针,-1时为没有运行进程
405     WaitPoint=-1;  // 阻塞队列指针,-1时为没有阻塞进程
406     ReadyPoint=-1; // 就绪队列指针,-1时为没有就绪进程
407     ClockNumber=0;   // 系统时钟
408     ProcNumber=0;    // 当前系统中的进程总数
409     
410     system("cls") ;
411     while ( true )                           
412     {
413         printf("***********************************\n");
414         printf("     1: 建立进程调度数据序列 \n") ;
415         printf("     2: 执行调度算法\n") ;
416         printf("     3: 显示调度结果 \n") ;
417         printf("     4: 更改时间片 \n");
418         printf("     5: 退出\n") ;
419         printf("***********************************\n");
420         printf( "Enter your choice (1 ~ 5): ");  
421         
422         do{   //如果输入信息不正确,继续输入
423             ch = (char)_getch() ;
424         } while(ch != 1 && ch != 2&& ch != 3&& ch != 4&& ch != 5);
425         
426         if(ch == 5) { printf( "\n");return 0; }   // 选择4,退出       
427         if(ch == 3) DisResult();        // 选择3        
428         if(ch == 2) Scheduler_FF();     // 选择2        
429         if(ch == 1) Create_ProcInfo();  // 选择1        
430         if(ch == 4) Change_q();
431         _getch() ; 
432         system("cls") ;
433     }
434     //结束
435     printf("\nPress Any Key To Continue:");
436     _getch() ; 
437     return 0;
438 }

 

操作系统,时间片轮转算法的C语言实现Round Robin

标签:float   read   etc   play   控制   pre   返回   and   star   

原文地址:https://www.cnblogs.com/lancelee98/p/9991651.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!