zoukankan      html  css  js  c++  java
  • 实验三 进程调度模拟程序

    1. 目的和要求
    实验目的

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

    实验要求

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

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

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

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

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

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

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

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

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

    3. 实验原理及核心算法
    “轮转法”有简单轮转法、多级反馈队列调度算法。

    (1). 简单轮转法的基本思想是:

    所有就绪进程按 FCFS排成一个队列,总是把处理机分配给队首的进程,各进程占用CPU的时间片长度相同。如果运行进程用完它的时间片后还未完成,就把它送回到就绪队列的末尾,把处理机重新分配给队首的进程。直至所有的进程运行完毕。

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

    将就绪队列分为N级(N=3~5),每个就绪队列优先数不同并且分配给不同的时间片:队列级别越高,优先数越低,时间片越长;级别越小,优先数越高,时间片越短。

    系统从第一级调度,当第一级为空时,系统转向第二级队列,.....当处于运行态的进程用完一个时间片,若未完成则放弃CPU,进入下一级队列。

    当进程第一次就绪时,进入第一级队列。

    4. 实验环境
    自主选择实验环境。可以选用Turbo C作为开发环境。也可以选用Windows下的可视化环境,利用各种控件较为方便。

    5. 实验环境

        1.源程序名Gg.c

            可执行程序名:Gg.exe

        2.原理分析及流程图

           输入全部进程,程序自动遵循简单轮转法的要求开始运行,最后输出结果。

      1 #include"stdio.h"
      2 #include"stdlib.h"
      3 #include"string.h"
      4 typedef struct node
      5 {
      6 char name[10]; //进程标志符
      7 int prio; //进程优先数
      8 int cputime; //进程占用cpu时间
      9 int needtime; //进程到完成还要的时间
     10 char state; //进程的状态
     11 struct node *next; //链指针
     12 }PCB;
     13 PCB *finish,*ready,*tail,*run; //队列指针
     14 int N; //进程数
     15 //将就绪队列的第一个进程投入运行
     16 firstin()
     17 {
     18 run=ready; //就绪队列头指针赋值给运行头指针
     19 run->state='R'; //进程状态变为运行态
     20 ready=ready->next; //就绪列头指针后移到下一进程
     21 }//标题输出函数
     22 void prt1(char a)
     23 {
     24 printf("进程号 cpu时间 所需时间 优先数 状态
    ");
     25 
     26 }
     27 //进程PCB输出
     28 void prt2(char a,PCB *q)
     29 { //优先数算法输出
     30 printf(" % -10s% -10d% -10d% -10d %c
    ",q->name,q->cputime,q->needtime,q->prio,q->state);
     31 }
     32 //输出函数
     33 void prt(char algo)
     34 {
     35 PCB *p;
     36 prt1(algo); //输出标题
     37 if(run!=NULL) //如果运行标题指针不空
     38 prt2(algo,run); //输出当前正在运行的PCB
     39 p=ready; //输出就绪队列PCB
     40 while(p!=NULL)
     41 {
     42 prt2(algo,p);
     43 p=p->next;
     44 }
     45 p=finish; //输出完成队列的PCB
     46 while(p!=NULL) 
     47 {
     48 prt2(algo,p);
     49 p=p->next;
     50 }
     51 getchar(); //按任意键继续
     52 }
     53 //优先数的算法插入算法
     54 insert1(PCB *q)
     55 {
     56 PCB *p1,*s,*r;
     57 int b;
     58 s=q; //待插入的PCB指针
     59 p1=ready; //就绪队列头指针
     60 r=p1; //r做p1的前驱指针
     61 b=1;
     62 while((p1!=NULL)&&b) //根据优先数确定插入位置
     63 if(p1->prio>=s->prio)
     64 {
     65 r=p1;
     66 p1=p1->next;
     67 }
     68 else
     69 b=0;
     70 if(r!=p1) //如果条件成立说明插入在r与p1之间
     71 {
     72 r->next=s;
     73 s->next=p1;
     74 }
     75 else
     76 {
     77 s->next=p1; //否则插入在就绪队列的头
     78 ready=s;
     79 }
     80 }
     81 //优先数创建初始PCB信息
     82 void create1(char alg)
     83 {
     84 PCB *p;
     85 int i,time;
     86 char na[10];
     87 ready=NULL; //就绪队列头文件
     88 finish=NULL; //完成队列头文件
     89 run=NULL; //运行队列头文件
     90 printf("输入进程号和运行时间:
    "); //输入进程标志和所需时间创建PCB
     91 for(i=1;i<=N;i++)
     92 {
     93 p=(PCB *)malloc(sizeof(PCB));
     94 scanf("%s",na);
     95 scanf("%d",&time);
     96 strcpy(p->name,na);
     97 p->cputime=0;
     98 p->needtime=time;
     99 p->state='w';
    100 p->prio=50-time;
    101 if(ready!=NULL) //就绪队列不空,调用插入函数插入
    102 insert1(p);
    103 else
    104 {
    105 p->next=ready; //创建就绪队列的第一个PCB
    106 ready=p;
    107 }
    108 }
    109 //clrscr();
    110 printf(" 优先数算法输出信息:
    ");
    111 printf("***********************************************
    ");
    112 prt(alg); //输出进程PCB信息
    113 run=ready; //将就绪队列的第一个进程投入运行
    114 ready=ready->next;
    115 run->state='R';
    116 }
    117 //优先数调度算法
    118 void priority(char alg)
    119 {
    120 while(run!=NULL) //当运行队列不空时,有进程正在运行
    121 {
    122 run->cputime=run->cputime+1;
    123 run->needtime=run->needtime-1;
    124 run->prio=run->prio-3; //每运行一次优先数降低3个单位
    125 if(run->needtime==0) //如所需时间为0将其插入完成队列
    126 {
    127 run->next=finish;
    128 finish=run;
    129 run->state='F'; //置状态为完成态
    130 run=NULL; //运行队列头指针为空
    131 if(ready!=NULL) //如就绪队列不空                              
    132 firstin(); //将就绪队列的第一个进程投入运行
    133 }
    134 else //没有运行完同时优先数不是最大,则将其变为就绪态插入到就绪队列
    135 if((ready!=NULL)&&(run->prio<ready->prio))
    136 {
    137 run->state='W';
    138 insert1(run);
    139 firstin(); //将就绪队列的第一个进程投入运行
    140 }
    141 prt(alg); //输出进程PCB信息
    142 }
    143 }                                                                 
    144 //主函数
    145 void main()
    146 {
    147 char algo; //算法标记
    148 //clrscr();
    149 
    150 printf("输入进程数:
    ");
    151 scanf("%d",&N); //输入进程数
    152 create1(algo); //优先数算法
    153 priority(algo);
    154 }

    6.实验总结

      这次实验难度很大,我思考了很久,因为我最好的方法就是运用指针队列,但是我指针队列方面的知识已经忘记很多了,这对我来说十分困难。最后自己在网上的搜索和同学老师的指导我还是做出来了。

  • 相关阅读:
    LeetCode Subsets II
    LeetCode Rotate Image
    LeetCode Palidrome Number
    LeetCode Generate Parentheses
    LeetCode Maximum Subarray
    LeetCode Set Matrix Zeroes
    LeetCode Remove Nth Node From End of List
    Linux Loop设备 使用
    Linux 文件系统大小调整
    LeetCode N-Queens II
  • 原文地址:https://www.cnblogs.com/TonyWinner/p/5017040.html
Copyright © 2011-2022 走看看