• 【操作系统】实验三 进程调度模拟程序


    实验三、进程调度模拟程序实验

    商软1班   杨晶晶  201406114102

    一、        实验目的

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

    二、        实验内容和要求

        1.2.1例题:设计一个有 N个进程并发执行的进程调度模拟程序。

    进程调度算法:采用最高优先级优先的调度算法(即把处理机分配给优先级最高的进程)和先来先服务(若优先级相同)算法。

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

    (2).  进程的优先级及需要的运行时间可以事先人为地指定,进程的运行时间以时间片为单位进行计算。

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

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

    (5).  如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时应将进程的优先数减1(即降低一级),然后把它插入就绪队列等待调度。

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

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

    1.2.2实验题A:编写并调试一个模拟的进程调度程序,采用“最高优先数优先”调度算法对N(N不小于5)个进程进行调度。

    “最高优先级优先”调度算法的基本思想是把CPU分配给就绪队列中优先数最高的进程。

    (1). 静态优先数是在创建进程时确定的,并在整个进程运行期间不再改变。

    (2). 动态优先数是指进程的优先数在创建进程时可以给定一个初始值,并且可以按一定规则修改优先数。例如:在进程获得一次CPU后就将其优先数减少1,并且进程等待的时间超过某一时限(2个时间片时间)时增加其优先数等。

    (3). (**)进程的优先数及需要的运行时间可以事先人为地指定,(也可以由随机数产生)。

    (4). (**)在进行模拟调度过程可以创建(增加)进程,其到达时间为进程输入的时间。

    1.2.3实验题B:编写并调试一个模拟的进程调度程序,采用“基于时间片轮转法”调度算法对N(N不小于5)个进程进行调度。 “轮转法”有简单轮转法、多级反馈队列调度算法。

    (1). 简单轮转法的基本思想是:所有就绪进程按 FCFS排成一个队列,总是把处理机分配给队首的进程,各进程占用CPU的时间片长度相同。如果运行进程用完它的时间片后还未完成,就把它送回到就绪队列的末尾,把处理机重新分配给队首的进程。直至所有的进程运行完毕。(此调度算法是否有优先级?)

     (2). 多级反馈队列调度算法的基本思想是:

    将就绪队列分为N级(N=3~5),每个就绪队列优先数不同并且分配给不同的时间片:队列级别越高,优先数越低,时间片越长;级别越小,优先数越高,时间片越短。系统从第一级调度,当第一级为空时,系统转向第二级队列,.....当处于运行态的进程用完一个时间片,若未完成则放弃CPU,进入下一级队列。当进程第一次就绪时,进入第一级队列。

    (3). (**)考虑进程的阻塞状态B(Blocked)增加阻塞队列。进程的是否阻塞和阻塞的时间由产生的“随机数”确定(阻塞的频率和时间长度要较为合理)。注意进程只有处于运行状态才可能转换成阻塞状态,进程只有处于就绪状态才可以转换成运行状态。

    2.    实验内容

    根据指定的实验课题:A(1),A(2),B(1)和B(2)完成设计、编码和调试工作,完成实验报告。

    注:带**号的条目表示选做内容。

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

    1.      源程序名:3.c

    可执行程序名:3.exe

    2.      原理分析及流程图

      

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

      1 #include <stdio.h>
      2 #include <stdlib.h> 
      3 #include <conio.h> 
      4 #define getpch(type) (type*)malloc(sizeof(type)) 
      5 #define N 3
      6 int count;
      7 sort2();
      8 struct pcb { /* 定义进程控制块PCB */ 
      9        char name[10]; 
     10        char status; 
     11        int prio; 
     12        int ntime; 
     13        int rtime; 
     14        struct pcb* link; 
     15 }*ready=NULL,*p; 
     16 
     17 typedef struct pcb PCB; 
     18   
     19 struct pcb2 { /* 定义进程控制块PCB2 */ 
     20        char name[10]; 
     21        char status; 
     22        int prio;
     23        int atime;
     24        int ntime; 
     25        int runtime;
     26        int restime;
     27 }pcb[24]; 
     28 
     29 input2() /* 输入数据*/ 
     30 { 
     31   int i,num; 
     32  
     33   printf("
     请输入进程数:"); 
     34   scanf("%d",&num);
     35   count=num;
     36   for(i=0;i<num;i++) 
     37   { 
     38     printf("进程号No.%d:",i); 
     39     printf("
    输入进程名:"); 
     40     scanf("%s",pcb[i].name); 
     41     printf("输入进程到达时间:"); 
     42     scanf("%d",&pcb[i].atime); 
     43     
     44     printf("输入进程运行时间:"); 
     45     scanf("%d",&pcb[i].ntime); 
     46     printf("
    "); 
     47     pcb[i].runtime=0;
     48     pcb[i].status='r'; 
     49     pcb[i].restime=pcb[i].ntime;
     50   
     51   }
     52   sort2();
     53   printf("
    
    ----------------FCFS排序之后-------------------
    ");
     54   printf("进程名  到达时间  需要运行时间
    ");
     55   for(i=0;i<num;i++)
     56   {
     57      printf("%s        %d         %d 
    ",pcb[i].name,pcb[i].atime,pcb[i].ntime);
     58   }
     59 
     60 } 
     61 
     62 sort2()/* 进程按时间的先后排序*/
     63 {
     64     
     65     int i,j;
     66     struct pcb2 t;
     67     for(i=0;i<count-1;i++) //按进程到达时间的先后排序
     68     {                               //如果两个进程同时到达,按在屏幕先输入的先运行
     69         for(j=i+1;j<count;j++)
     70         { 
     71             if(pcb[j].atime< pcb[i].atime)
     72             {
     73                 t=pcb[j];
     74                 pcb[j]=pcb[i];
     75                 pcb[i]=t;
     76             }
     77 
     78         }
     79     }
     80 }
     81   
     82 sort() /* 进程进行优先级排列函数*/ 
     83 { 
     84   PCB *first, *second; 
     85   int insert=0; 
     86   if((ready==NULL)||((p->prio)>(ready->prio))) /*优先级最大者,插入队首*/ 
     87   { 
     88     p->link=ready; 
     89     ready=p; 
     90   } 
     91   else /* 进程比较优先级,插入适当的位置中*/ 
     92   { 
     93     first=ready; 
     94     second=first->link; 
     95     while(second!=NULL) 
     96     { 
     97       if((p->prio)>(second->prio)) /*若插入进程比当前进程优先数大,*/ 
     98       { /*插入到当前进程前面*/ 
     99         p->link=second; 
    100         first->link=p; 
    101         second=NULL; 
    102         insert=1; 
    103       } 
    104       else /* 插入进程优先数最低,则插入到队尾*/ 
    105       { 
    106         first=first->link; 
    107         second=second->link; 
    108       } 
    109     } 
    110     if(insert==0) first->link=p; 
    111   } 
    112 } 
    113  
    114 input() /* 建立进程控制块函数*/ 
    115 { 
    116   int i,num; 
    117   /*clrscr();  */   /*清屏*/
    118   printf("
    请输入进程数:"); 
    119   scanf("%d",&num); 
    120   for(i=0;i<num;i++) 
    121   { 
    122     printf("
    进程号No.%d:
    ",i); 
    123     p=getpch(PCB);  /*宏(type*)malloc(sizeof(type)) */
    124     printf("
    输入进程名:"); 
    125     scanf("%s",p->name); 
    126     /*printf("
     输入进程优先数:"); 
    127     scanf("%d",&p->prio); */
    128     p->prio=N;
    129     printf("
    输入进程运行时间:"); 
    130     scanf("%d",&p->ntime); 
    131     printf("
    "); 
    132     p->rtime=0;p->status='r'; 
    133     p->link=NULL; 
    134     sort(); /* 调用sort函数*/ 
    135   } 
    136 
    137 } 
    138 
    139 int space() 
    140 { 
    141   int l=0; PCB* pr=ready; 
    142   while(pr!=NULL) 
    143   { 
    144   l++; 
    145   pr=pr->link; 
    146   } 
    147   return(l); 
    148 } 
    149 
    150 disp(PCB * pr) /*单个进程显示函数*/ 
    151 {  
    152   printf("|%s	",pr->name); 
    153   printf("|%c	",pr->status); 
    154   printf("|%d	",pr->prio); 
    155   printf("|%d	",pr->ntime); 
    156   printf("|%d	",pr->rtime); 
    157   printf("
    "); 
    158 } 
    159 
    160 void printbyprio(int prio)
    161 {
    162   PCB* pr; 
    163   pr=ready; 
    164   printf("
     ****当前第%d级队列(优先数为%d)的就绪进程有:
    ",(N+1)-prio,prio); /*显示就绪队列状态*/ 
    165   printf("
     qname 	status	 prio 	ndtime	 runtime 
    "); 
    166   while(pr!=NULL) 
    167   { 
    168     if (pr->prio==prio) disp(pr); 
    169     pr=pr->link; 
    170   } 
    171 }
    172 
    173 check() /* 显示所有进程状态函数 */ 
    174 { 
    175   PCB* pr; 
    176   int i;
    177   printf("
     /\/\/\/\当前正在运行的进程是:%s",p->name); /*显示当前运行进程*/ 
    178    printf("
     qname 	status	 prio 	ndtime	 runtime 
    "); 
    179   disp(p); /*单个进程显示函数*/ 
    180   
    181   printf("
     当前就绪队列状态为:
    "); 
    182   for(i=N;i>=1;i--)
    183     printbyprio(i);/*显示就绪队列状态*/ 
    184   /*
    185   while(pr!=NULL) 
    186   { 
    187     disp(pr); 
    188     pr=pr->link; 
    189     } 
    190   */
    191 } 
    192 
    193 destroy() /*进程撤消函数(进程运行结束,撤消进程)*/ 
    194 { 
    195   printf("
    进程 [%s] 已完成.
    ",p->name); 
    196   free(p); 
    197 } 
    198 
    199 running() /* 运行函数。判断是否完成,完成则撤销,否则置就绪状态并插入就绪队列*/ 
    200 { 
    201   int slice,i;
    202   slice=1;
    203   for(i=1;i<((N+1)-p->prio);i++)
    204     slice=slice*2;
    205     
    206   for(i=1;i<=slice;i++)
    207   {
    208      (p->rtime)++; 
    209      if (p->rtime==p->ntime)
    210        break;
    211        
    212   }
    213   if(p->rtime==p->ntime) 
    214       destroy(); /*进程撤消函数(进程运行结束,撤消进程)*/
    215   else 
    216   { 
    217     if(p->prio>1) (p->prio)--; 
    218     p->status='r'; 
    219     sort(); /* 进程进行优先级排列函数*/ 
    220   } 
    221 } 
    222 
    223 void cteatpdisp()
    224 /*显示(运行过程中)增加新进程后,所有就绪队列中的进程*/
    225 { 
    226  
    227   int i;
    228    
    229   printf("
    当增加新进程后,所有就绪队列中的进程(此时无运行进程):
    "); /*显示就绪队列状态*/ 
    230   for(i=N;i>=1;i--)
    231     printbyprio(i);
    232 }
    233 void creatp()//是否添加新进程
    234 {
    235      char temp;
    236      printf("
    是否要添加新进程?输入Y/y表示添加");
    237      scanf("%c",&temp);
    238      if (temp=='y'||temp=='Y')
    239      {
    240         input();
    241         cteatpdisp();/*显示(运行过程中)增加新进程后,所有就绪队列中的进程*/
    242      }    
    243 }
    244 
    245 PRIO()//最高优先数优先调度算法
    246 {
    247   int len,h=0; 
    248   char ch; 
    249   input(); 
    250   len=space(); 
    251   while((len!=0)&&(ready!=NULL)) 
    252   { 
    253     ch=getchar(); 
    254     /*getchar();*/
    255     h++; 
    256     printf("
    正在运行的进程数:%d ",h); 
    257     p=ready; 
    258     ready=p->link; 
    259     p->link=NULL; 
    260     p->status='R'; 
    261     check(); /* 显示所有进程状态函数 */ 
    262     running(); /* 运行函数。判断是否完成,完成则撤销,否则置就绪状态并插入就绪队列*/ 
    263     creatp();//是否添加新进程
    264     printf("
     按任一键继续......"); 
    265     ch=getchar(); 
    266   } 
    267   printf("
    
    进程已经完成.
    "); 
    268   ch=getchar(); 
    269   ch=getchar();
    270 }
    271 QueueSort()
    272 {
    273     int i;
    274     struct pcb2 t;
    275     t=pcb[0];
    276     for(i=1;i<count;i++)
    277         pcb[i-1]=pcb[i];
    278     pcb[0].restime--;
    279     pcb[count-1]=t;
    280 
    281 }
    282 QueueSort1()
    283 {
    284     int i;
    285 
    286     for(i=1;i<count;i++)
    287         pcb[i-1]=pcb[i];
    288     count--;
    289 }
    290 RR()//时间片轮转法调度算法
    291 {
    292     int timeflag=0;
    293     int timepiece=2;
    294     int T;
    295     printf("
    请输入时间片:");
    296     scanf("%d",&T);
    297     int k;
    298     char ch;
    299     input2();
    300     sort2();
    301     while(count>=0)
    302     {
    303         if(timeflag==T)
    304         {
    305             timeflag=0;
    306             if(pcb[0].restime==0)
    307             {
    308             printf("进程%s已完成
    ",pcb[0].name);
    309             
    310 
    311             if(count!=0){
    312                 QueueSort1();
    313                 printf("当前正在运行进程是:%s
    ",pcb[0].name);
    314             }
    315             if(count>=1)
    316                 for(k=1;k<count;k++)
    317                 printf("进程%s正在等待
    ",pcb[k].name);
    318             if(count==0){
    319                 pcb[0].restime--;
    320                 count--;
    321             }
    322             }
    323             else{
    324                 QueueSort();
    325                 if(count!=0){
    326                 //QueueSort1();
    327                 printf("当前正在运行进程是:%s
    ",pcb[0].name);
    328                 }
    329                 if(count>=1)
    330                 for(k=1;k<count;k++)
    331                 printf("进程%s正在等待
    ",pcb[k].name);
    332             }              
    333         }
    334         else{
    335             if(pcb[0].restime==0)
    336             {
    337             printf("进程%s已完成
    ",pcb[0].name);
    338             if(count!=0){
    339                 QueueSort1();
    340                 printf("进程%s正在运行
    ",pcb[0].name);
    341             }
    342             if(count>=1)
    343                 for(k=1;k<count;k++)
    344                 printf("进程%s正在等待
    ",pcb[k].name);
    345             }
    346             else{
    347                 pcb[0].restime--;
    348                 if(count!=0)
    349                 printf("进程%s正在运行
    ",pcb[0].name);
    350             
    351                 if(count>=1)
    352                 for(k=1;k<count;k++)
    353                 printf("进程%s正在等待
    ",pcb[k].name);
    354             }
    355         }
    356         timeflag++;
    357         printf("
     按任一键继续......"); 
    358         ch=getchar(); 
    359         ch=getchar();
    360     }
    361      printf("
    
     全部进程已经完成.
    "); 
    362 }  
    363 main() /*主函数*/ 
    364 { 
    365   int i, jobNum, choi;
    366     char flag=0; 
    367     printf("_________________________________
    ");
    368     printf("1.最高优先数优先调度算法
    ");
    369     printf("2.时间片轮转法调度算法
    ");
    370     printf("3.退出
    ");
    371     printf("_________________________________
    ");
    372     printf("****你的选择是:");
    373     scanf("%d", &choi);
    374     switch(choi)
    375     {
    376     case 1:
    377         PRIO(); //最高优先数优先调度算法
    378         main();
    379         break;        
    380     case 2:
    381         RR();//时间片轮转法调度算法
    382         main();
    383         break;
    384     case 3:
    385         break;
    386     default:
    387         printf("
     !!!!!输入错误,请重新选择!!!!!
    ");
    388         main();
    389         
    390     }
    391   
    392 }

    4.      运行结果及分析

     

     

    四、        实验总结

    一开始不是很清楚进程调度和作业调度的区别,通过这个实验更加清楚了进程调度与作业调度的差别。更加清楚最高优先数优先调度算法和时间片轮转发调度的具体算法。不过还是不够了解,问了同学也查找了一些资料才解决问题。很多细节的地方还是要多注意,多练习多看书。

     

     

     

  • 相关阅读:
    canvas裁剪之后的base64转换为上传文件blob对象
    最简单的数据饼状图
    vue2源码浏览分析02
    vue2源码浏览分析01
    非常适合新手的jq/zepto源码分析07---ajax的封装
    非常适合新手的jq/zepto源码分析08---ajax的封装
    非常适合新手的jq/zepto源码分析06 -- 事件模型
    非常适合新手的jq/zepto源码分析05
    非常适合新手的jq/zepto源码分析03
    非常适合新手的jq/zepto源码分析04
  • 原文地址:https://www.cnblogs.com/jjy520/p/5487489.html
Copyright © 2020-2023  润新知