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


    实验三 进程调度模拟程序

    网络工程专业   姓名:蔡利聪  学号:201306114117

    一、目的和要求

    1. 实验目的

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

    2.实验要求

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

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

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

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

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

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

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

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

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

    二、实验内容

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

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

    1.    源程序名:动态优先数简化.cpp,可执行程序名:动态优先数简化.exe

    2.    原理分析

    (1)“最高优先级优先”调度算法的基本思想是把CPU分配给就绪队列中优先数最高的进程。动态优先数是指进程的优先数在创建进程时可以给定一个初始值,并且可以按一定规则修改优先数。例如:在进程获得一次CPU后就将其优先数减少1,并且进程等待的时间超过某一时限(2个时间片时间)时增加其优先数等。

    (2)定义进程控制块的结构体和程序工作时间的结构体,pcb可以包含以下信息:进程控制块包含如下信息:进程名、优先级、到达时间、需要运行时间、已用CPU时间、进程状态等等。

    (3)通过构造进程输入input(),进程运行结果输出output(),disp(),以及使整个程序正常运行的函数块等,通过主函数调用方法函数的想法来实现进程调度模拟。

    (4)在对进程控制块的访问和调用通过链表指针的形式,在进程控制块输入后,会显示输入的内容,并把每一个作业运行的状态都能在程序中体现出来。

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

      1 #include<stdio.h>
      2 #include <stdlib.h>
      3 #include <conio.h>
      4 #define getpch(type) (type*)malloc(sizeof(type))
      5 #define NULL 0
      6 struct pcb { /* 定义进程控制块PCB */
      7 char name[10];
      8 char state;
      9 int super;
     10 int ntime;
     11 int rtime;
     12 struct pcb* link;
     13 }*ready=NULL,*p;
     14 typedef struct pcb PCB;
     15  
     16 void sort() /* 建立对进程进行优先级排列函数*/
     17 {
     18     PCB *first, *second;
     19     int insert=0;
     20     if((ready==NULL)||((p->super)>(ready->super))) /*优先级最大者,插入队首*/
     21     {
     22         p->link=ready;
     23         ready=p;
     24     }
     25     else /* 进程比较优先级,插入适当的位置中*/
     26     {
     27         first=ready;
     28         second=first->link;
     29         while(second!=NULL)
     30         {
     31             if((p->super)>(second->super)) /*若插入进程比当前进程优先数大,*/
     32             { /*插入到当前进程前面*/
     33                 p->link=second;
     34                 first->link=p;
     35                 second=NULL;
     36                 insert=1;
     37             }
     38             else /* 插入进程优先数最低,则插入到队尾*/
     39             {
     40                 first=first->link;
     41                 second=second->link;
     42             }
     43         }
     44     }
     45 }
     46 void input() /* 建立进程控制块函数*/
     47 {
     48     int i,num;
     49     //clrscr(); /*清屏*/
     50     printf("
     请输入进程个数?");//
     51     scanf("%d",&num);
     52     for(i=0;i<num;i++)
     53     {
     54          printf("
     进程号No.%d:
    ",i);
     55          p=getpch(PCB);
     56          printf("
     输入进程名:");
     57          scanf("%s",p->name);
     58          printf("
     输入进程优先数:");
     59          scanf("%d",&p->super);
     60          printf("
     输入进程运行时间:");
     61          scanf("%d",&p->ntime);
     62          printf("
    ");
     63          p->rtime=0;p->state='w';
     64          p->link=NULL;
     65          sort(); /* 调用sort函数*/
     66     }
     67 }
     68 int space()
     69 {
     70      int l=0; PCB* pr=ready;
     71      while(pr!=NULL)
     72      {
     73          l++;
     74          pr=pr->link;
     75      }
     76      return(l);
     77 }
     78 void disp(PCB * pr) /*建立进程显示函数,用于显示当前进程*/
     79 {
     80      printf("
     进程名	状态 	优先级 	所需时间 	运行时间 
    ");
     81      printf("%s	",pr->name);
     82      printf(" %c	",pr->state);
     83      printf("  %d	",pr->super);
     84      printf("   %d	",pr->ntime);
     85      printf("           %d	",pr->rtime);
     86      printf("
    ");
     87 }
     88 void check() /* 建立进程查看函数 */
     89 {
     90      PCB* pr;
     91      printf("
     **** 当前正在运行的进程是:%s",p->name); /*显示当前运行进程*/
     92      disp(p);
     93      pr=ready;
     94      printf("
     ****当前就绪队列状态为:
    "); /*显示就绪队列状态*/
     95      while(pr!=NULL)
     96      {
     97          disp(pr);
     98          pr=pr->link;
     99      }
    100 }
    101 void destroy() /*建立进程撤消函数(进程运行结束,撤消进程)*/
    102 {
    103      printf("
     进程 [%s] 已完成.
    ",p->name);
    104      free(p);
    105 }
    106 void running() /* 建立进程就绪函数(进程运行时间到,置就绪状态)*/
    107 {
    108     (p->rtime)++;
    109     if(p->rtime==p->ntime)
    110         destroy(); /* 调用destroy函数*/
    111     else
    112     {
    113         (p->super)--;
    114         p->state='w';
    115         sort(); /*调用sort函数*/
    116     }
    117 }
    118 int main() /*主函数*/
    119 {
    120     int len,h=0;
    121     char ch;
    122     input();
    123     len=space();
    124     while((len!=0)&&(ready!=NULL))
    125     {
    126          ch=getchar();
    127          h++;
    128          printf("
     The execute number:%d 
    ",h);
    129          p=ready;
    130          ready=p->link;
    131          p->link=NULL;
    132          p->state='R';
    133          check();
    134          running();
    135          printf("
     按任一键继续......");
    136          ch=getchar();
    137     }
    138     printf("
    
     进程已经完成.
    ");
    139     ch=getchar();
    140 }

     4.       运行结果

     

    以上图所示,当输入3个进程控制块的的信息后,进程执行结果符合根据计算的结果,表明此程序达到预期效果。

    实验总结

    (1)本次实验是对作业调度程序的补充,本次实验需要对每个进程的执行过程的先后顺序的结果进行显示,所以需要考虑每个进程的优先级,即要先进行排序,然后才能执行进程的调度。 

    (2)通过本次实验,我觉得关于数据结构的算法和语法的基础知识很重要,特别是编写C语言程序时,涉及到一些复杂的程序,都会用到这些知识,由于数据结构基础知识学得不扎实,所以写代码遇到很多困难。虽然会定义结构体比较熟练,但是对于在程序中调用结构体就不太理解,导致多次出错,并通过查阅相关资料,然后不断修改,才把相关的实验基础要求完成。另外,写程序需要很好的思维习惯,并且要善于转化计算机操作与实际情况,才能把代码理解透,往后需要多多练习,形成自己的编程习惯和思维习惯。

  • 相关阅读:
    textarea聚焦的多种写法
    vue.js入门
    全选,反选
    jquery列表,点击反应
    SqlServer中offset..fetch 的使用问题
    复习Spring第四课---Spring对国际化的支持
    SqlServer的order by问题
    设计模式之---代理模式
    解决SpringMVC重复提交的问题
    Java知识复习(三)
  • 原文地址:https://www.cnblogs.com/clcbk/p/4518920.html
Copyright © 2020-2023  润新知