zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Less(27a)GET
    Less(27)GET
    虚拟机打开文件黑屏
    mysql开放远程连接权限
    fidder如何设置代理转发
    如何获取APK的包名
    ADB调试原理之通俗版本
    adb端口5037被占用怎么办
    ADB调试原理
    如何使用无线调试手机
  • 原文地址:https://www.cnblogs.com/ynly/p/13034454.html
Copyright © 2011-2022 走看看