zoukankan      html  css  js  c++  java
  • 39 进程调度实验

    一、 实验目的

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

    2.实验要求

    3.设计一个有 N(N不小于5)个进程并发执行的进程调度模拟程序。

    4.进程调度算法:“时间片轮转法”调度算法对N个进程进行调度。

     

    二、 实验内容和要求

    完成两个算法(简单时间片轮转法、多级反馈队列调度算法)的设计、编码和调试工作,完成实验报告。

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

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

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

    4) 如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,应把它插入就绪队列等待下一次调度。

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

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

     

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

    1.源程序名:1125.c

    可执行程序名:1125.exe

    2.原理分析及流程图

    1)理解简单轮转法与多级反馈队列调度算法;

    2)流程图:

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

      1 #include<stdio.h>
      2 
      3 #define MAX 24 
      4 
      5 typedef struct node
      6 {
      7     char name[10];//作业名
      8     int arrivetime;//作业到达时间
      9     int runtime;//作业所需的运行时间
     10     int usetime; //已用CPU时间 
     11     char stage; //进程的状态 
     12     int starttime; //开始时间
     13     int endtime; //结束时间 
     14     int zztime; //作业周转时间
     15     float zzxs; //周转系数 
     16 }JCB;
     17 
     18 static unsigned int N=5;  //作业数
     19 static int current=0, current1=0;  //当前时间
     20 static unsigned int j=-1, j1=-1; 
     21 JCB job[MAX];
     22 
     23 void Line();
     24 void FCFS();
     25 void getValue();
     26 void getValue1();
     27 void input();
     28 void print();
     29 void choice();
     30 void SJF();
     31 
     32 void getValue() 
     33 {
     34     unsigned int i;
     35     current=job[0].arrivetime;
     36     for(i=0; i<N; i++)   
     37     {
     38         if(job[i].stage=='r' && current>=job[i].arrivetime)
     39         {
     40             if(job[i].usetime==0)
     41                 job[i].starttime=current;
     42             job[i].stage='R';   //程序正在运行 
     43             job[i].usetime++;  //CPU的运行时间加1
     44             current++;
     45         }
     46         if(job[i].usetime==job[i].runtime && job[i].stage=='R')
     47         {
     48             j++;          //用来标记有多少进程完成了
     49             job[i].stage='F';
     50             job[i].endtime=current;
     51             job[i].zztime=job[i].endtime-job[i].arrivetime;
     52             job[i].zzxs=(float)job[i].zztime/(float)job[i].runtime;
     53         }
     54         if(job[i].stage!='F')
     55             job[i].stage='r';  //运行完之后变回就绪态 
     56         if(i==N-1)   //进入死循环了
     57             i=-1;
     58         if(j==N-1)
     59             break;
     60     }
     61 }
     62 
     63 void getValue1() 
     64 {
     65     unsigned int i=0, h, rest;
     66     current1=job[0].arrivetime;
     67     for(; i<N; i++)   
     68     {
     69         if(job[i].stage=='2')
     70         {
     71             h=0;
     72             while(h<N)     //判断当前时刻的这一级是否有进程
     73             {
     74                 if(job[h].stage=='r' && current1>=job[h].arrivetime)
     75                 {    
     76                     i=h;
     77                     h=N;
     78                 }
     79                 h++;
     80             }
     81         }
     82         else if(job[i].stage=='3')
     83         {
     84             h=0;
     85             while(h<N)     //判断当前时刻的这一级是否有进程
     86             {
     87                 if(job[h].stage=='2')
     88                 {    
     89                     i=h;
     90                     h=N;
     91                 }
     92                 h++;
     93             }
     94         }
     95         if(job[i].stage=='r' && current1>=job[i].arrivetime)      
     96         {
     97             if(job[i].usetime==0)
     98                 job[i].starttime=current1;
     99             job[i].stage='R';   //程序正在运行 
    100             job[i].usetime++;  //CPU的运行时间加1
    101             current1++;
    102             if(job[i].usetime==job[i].runtime)
    103             {
    104                 j1++;
    105                 job[i].stage='F';
    106                 job[i].endtime=current1;
    107                 job[i].zztime=job[i].endtime-job[i].arrivetime;
    108                 job[i].zzxs=(float)job[i].zztime/(float)job[i].runtime;
    109             }
    110             else    //还没完成则进入下一级
    111                 job[i].stage='2';
    112         }
    113         else if(job[i].stage=='2')
    114         {
    115             job[i].stage='R';
    116             job[i].usetime+=2;
    117             current1+=2;
    118             if(job[i].usetime>=job[i].runtime)
    119             {
    120                 j1++;
    121                 job[i].stage='F';
    122                 rest=job[i].usetime-job[i].runtime;
    123                 current1=current1-rest;
    124                 job[i].endtime=current1;
    125                 job[i].zztime=job[i].endtime-job[i].arrivetime;
    126                 job[i].zzxs=(float)job[i].zztime/(float)job[i].runtime;
    127             }
    128             else    //还没完成则进入下一级
    129                 job[i].stage='3';
    130         }
    131         else if(job[i].stage=='3')
    132         {
    133             job[i].stage='R';
    134             job[i].usetime+=4;
    135             current1+=4;
    136             if(job[i].usetime>=job[i].runtime)
    137             {
    138                 j1++;
    139                 job[i].stage='F';
    140                 rest=job[i].usetime-job[i].runtime;
    141                 current1=current1-rest;
    142                 job[i].endtime=current1;
    143                 job[i].zztime=job[i].endtime-job[i].arrivetime;
    144                 job[i].zzxs=(float)job[i].zztime/(float)job[i].runtime;
    145             }
    146             else    //还没完成则在最后一级继续轮转
    147                 job[i].stage='3';
    148         }
    149         if(i==N-1)   //进入死循环了
    150             i=-1;
    151         if(j1==N-1)
    152             break;
    153     }
    154 }
    155 
    156 void input()
    157 {
    158     int i, jobNum, choi;
    159     printf("1.自选作业个数
    ");
    160     printf("2.系统默认作业个数
    ");
    161     printf("你的选择是:");
    162     scanf("%d", &choi);
    163     switch(choi)
    164     {
    165     case 1:
    166         {
    167             do{
    168                 printf("
    Enter process number(作业个数应在2~24之间):");
    169                 scanf("%d", &jobNum);   //输入作业数 
    170                 N=jobNum;
    171                 printf("
    ");
    172             }while(N<2 || N>24);
    173             break;
    174         }    
    175     case 2:
    176         printf("
    系统默认作业个数为5");
    177         break;
    178     }
    179     for(i=0; i<jobNum; i++)
    180     {
    181         printf("
    job %d name:",i+1);
    182         scanf(" ");
    183         gets(job[i].name);    //输入作业名 
    184         printf("arrive time:");
    185         scanf(" %d",&job[i].arrivetime);    //输入作业达到时间 
    186         printf("running time:");
    187         scanf(" %d",&job[i].runtime);    //输入作业执行时间 
    188     }
    189 }
    190 
    191 void print()
    192 {
    193     unsigned int i;
    194     printf("     name  arrivetime  runtime  starttime  endtime  zztime  zzxs
    ");    
    195     for(i=0; i<N; i++)
    196     {
    197         printf("jod%d",i+1);
    198         printf("  %s		%d         %d         %d         %d        %d     %.2f
    ",job[i].name,job[i].arrivetime,job[i].runtime,job[i].starttime,job[i].endtime,job[i].zztime,job[i].zzxs);
    199     }
    200 }
    201 void choice()
    202 {
    203     int mark;
    204     do{
    205         printf("
    
    1. 简单轮转法;
    2. 多级反馈队列调度算法;
    3. 退出.");
    206         printf("
    Make choice: ");
    207         scanf("%d", &mark);
    208         switch(mark)
    209         {
    210             case 1:
    211                 FCFS();     //简单轮转法
    212
    break; 213 case 2: 214 SJF(); //多级反馈队列调度算法
    215 break; 216 case 3: 217 return; 218 default: 219 printf(" error!"); 220 } 221 }while(mark!=3); 222 } 223 224 void Line() 225 { 226 unsigned int a, b; 227 JCB mark; 228 current=0; current1=0; 229 j=-1; j1=-1; 230 for(a=0; a<N; a++) 231 { 232 job[a].usetime=0; 233 job[a].stage='r'; //就绪态 234 job[a].starttime=0; 235 job[a].endtime=0; 236 job[a].zztime=0; 237 job[a].zzxs=0; 238 } 239 for(a=0;a<N-1; a++) //通过到达时间整体排序 240 { 241 for(b=a+1; b<N; b++) 242 { 243 if(job[b].arrivetime<job[a].arrivetime) 244 { 245 mark=job[b]; 246 job[b]=job[a]; 247 job[a]=mark; 248 } 249 } 250 } 251 } 252 253 void FCFS() 254 { 255 Line(); 256 getValue(); //给每个作业内的相关参数赋值 257 print(); //打印出来 258 } 259 260 void SJF() 261 { 262 Line(); 263 getValue1(); 264 print(); //打印出来 265 } 266 267 void main() 268 { 269 input(); //输入 270 print(); //打印输出 271 choice(); //选择方式 272 }

    4.运行结果及分析

     

    图4.1 提示用户输入信息

    图4.2 简单轮转法结果

    图4.3 多级反馈队列调度算法结果

     

    四、 实验总结

         在前一次作业调度程序的基础上,改进成进程调度其实并不难,因为有那样的思维在里面,但是在做这次实验的过程中,首先理解简单轮转法和多级反馈跳读算法是很关键的,理解后顺着算法的思路编程,即使出现问题了,也能很快的找到是哪里的问题,并且不断地调试、改正,最后得到结果。

  • 相关阅读:
    CRUD工程师——嵌入式Web容器
    CRUD工程师——SpringBoot启动原理
    CRUD工程师——日志
    CRUD工程师——慢SQL
    CRUD工程师——索引
    前端专业术语: shim 和 Polyfill,了解下
    H5之postMessage 。实现跨域
    摘抄详细的VUE生命周期
    如何在不使用三大地图的KEY和相关组件的情况下,直接传参数到相关的H5地图
    Mac下通过brew安装指定版本的nodejs
  • 原文地址:https://www.cnblogs.com/1994-ann/p/5020897.html
Copyright © 2011-2022 走看看