zoukankan      html  css  js  c++  java
  • 操作系统,时间片轮转算法的C语言实现Round Robin

      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("
    ---------------------------
        建立了%2d 个进程数据序列
    
    ", ProcNumber);
     76     DisData();
     77     printf("
    Press 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("
            当前系统模拟%2d 个进程的运行    时钟:%ld
    
    ", ProcNumber,ClockNumber);
     94 
     95 printf("        就绪指针=%d, 运行指针=%d, 阻塞指针=%d
    
    ",ReadyPoint,RunPoint,WaitPoint );
     96 if(RunPoint!= -1)
     97 {
     98        printf(" 当前运行的进程   No.%d ID:%d
    ", RunPoint,proc[RunPoint].p_pid);
     99        printf("              %6d,%6d,%6d
    ",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 !
    ");
    105 
    106 n=ReadyPoint;
    107 printf("
     Ready Process ...... 
    ");
    108 while(n!=-1) // 显示就绪进程信息
    109 {   
    110        printf("     No.%d ID:%5d,%6d,%6d,%6d
    ",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("
     Waiting Process ...... 
    ");
    116 while(n!=-1) // 显示阻塞进程信息
    117 {   
    118        printf("     No.%d ID:%5d,%6d,%6d,%6d
    ",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("
    =================== 后备进程 ====================
    ");
    123 for(i=0; i<ProcNumber; i++) 
    124 if (proc[i].p_state=='B')
    125 printf("     No.%d ID:%5d,%6d
    ",i,proc[i].p_pid,proc[i].p_starttime); 
    126 
    127 printf("
    ================ 已经完成的进程 =================
    ");
    128 for(i=0; i<ProcNumber; i++) 
    129 if (proc[i].p_state=='F')
    130 printf("No.%d ID:%5d,%6d,%6d
    ",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("
    ---------------------------------
    ");
    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("
    " );
    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("
    " );
    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("若时间片未完,但进程已经结束
    ");
    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("进入阻塞队列
    ");
    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("时间片未完 程序未执行结束 继续执行
    ");
    242         return;
    243     }
    244     //{ printf("
     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("时间片完,但是程序未执行完 放到就绪队列尾部
    ");
    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("    必须首先建立进程调度数据 !  
    ");
    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("***********************************
    ");
    414         printf("     1: 建立进程调度数据序列 
    ") ;
    415         printf("     2: 执行调度算法
    ") ;
    416         printf("     3: 显示调度结果 
    ") ;
    417         printf("     4: 更改时间片 
    ");
    418         printf("     5: 退出
    ") ;
    419         printf("***********************************
    ");
    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( "
    ");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("
    Press Any Key To Continue:");
    436     _getch() ; 
    437     return 0;
    438 }
  • 相关阅读:
    解决"Windows没有足够信息,不能验证该证书"问题
    IPA 安装
    基于ECharts图表实现的股票K线图表(matols.com)
    WPF Chart
    IdentityServer4 中文文档
    企业信息系统
    手机网站的几点注意
    查询 SQL_Server 所有表的记录数: for xml path
    iframe在ipad safari的显示
    从WEB SERVICE 上返回大数据量的DATASET
  • 原文地址:https://www.cnblogs.com/lancelee98/p/9991651.html
Copyright © 2011-2022 走看看