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

一、实验目的

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

二、实验要求

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

1.模拟进程数据的生成

允许用户指定作业的个数(2-24),默认值为5。

允许用户选择输入每个进程的到达时间,所需运行时间,进程的运行时间以时间片为单位。

2. 模拟调度程序的功能

2.1 按照模拟数据的到达时间和所需运行时间,能分别执行以下调度算法。

FCFS

SJ

HRRN

RR

2.2 显示每种算法下各进程的调度执行顺序。

2.3计算各进程的开始执行时间,各作业的完成时间,周转时间和带权周转时间(周转系数)。

2.4模拟数据结果分析:对同一组模拟数据,比较各算法的平均周转时间,周转系数。

三、实验说明

1)  先来先服务(FCFS)调度算法,即按作业到达的先后次序进行调度。总是首先调度在系统中等待时间最长的作业。

2)  短作业优先 (SJF) 调度算法,优先调度要求运行时间最短的作业。

3)  响应比高者优先(HRRN)调度算法,为每个作业设置一个优先权(响应比),调度之前先计算各作业的优先权,优先数高者优先调度。RP (响应比)= 作业周转时间 / 作业运行时间=1+作业等待时间/作业运行时间。

4)  时间片轮转(RR)调度算法:调度程序每次把CPU分配给就绪队列首进程使用一个时间片,就绪队列中的每个进程轮流地运行一个时间片。当这个时间片结束时,强迫一个进程让出处理器,让它排列到就绪队列的尾部,等候下一轮调度。

四、实验环境

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

五.代码

#include<stdio.h>

   #include <stdlib.h>

   #include <conio.h>

   #define getpch(type) (type*)malloc(sizeof(type))    //为进程创建一个空间

   

   struct worktime{

      float Tb;             //作业运行时刻

       float Tc;             //作业完成时刻

      float Ti;             //周转时间

      float Wi;            //带权周转时间

  };

  

  struct jcb {             

      char name[10];        //作业名

      float arrivetime;        //作业到达时间

      float runtime;        //作业所需的运行时间

      char resource;        //所需资源

      float Rp;             //后备作业响应比

      char state;           //作业状态

      int worked_time;      //已运行时间  

     struct worktime wt;

      int need_time;       //需要运行的时间

      int flag;             //进程结束标志

      struct jcb* link;     //链指针

  }*ready=NULL,*p;

  

  typedef struct jcb JCB;//重命名结构体

  float T=0;

  int N;

  JCB *front,*rear;      

  

  void sort()    

  {

      JCB *first, *second;

      int insert=0;  //插入数

      if((ready==NULL)||((p->arrivetime)<(ready->arrivetime))) 

     {

          p->link=ready;

          ready=p;

         T=p->arrivetime;

          p->Rp=1;

      }

      else

      {

          first=ready;

          second=first->link;

          while(second!=NULL)

          {

              if((p->arrivetime)<(second->arrivetime))

              {

                  p->link=second;

                  first->link=p;

                  second=NULL;

                  insert=1;

              }

              else

              {

                  first=first->link;

                  second=second->link;

              }

          }

          if (insert==0) first->link=p;

     }

  }

  

  void SJFget()

  {

      JCB *front,*mintime,*rear;

      int ipmove=0;

      mintime=ready;

      rear=mintime->link;

      while(rear!=NULL)

      {

          if ((rear!=NULL)&&(T>=rear->arrivetime)&&(mintime->runtime)>(rear->runtime))

          {

              front=mintime;

              mintime=rear;

              rear=rear->link;

            ipmove=1;

         }

          else

             rear=rear->link;

     }

     if (ipmove==1)

     {

         front->link=mintime->link;

         mintime->link=ready;

    }

    ready=mintime;

 }

 void HRNget()

 {

     JCB *front,*mintime,*rear;

    int ipmove=0;

     mintime=ready;

    rear=mintime->link;

     while(rear!=NULL)

        if ((rear!=NULL)&&(T>=rear->arrivetime)&&(mintime->Rp)<(rear->Rp))

        {

            front=mintime;

            mintime=rear;

            rear=rear->link;

            ipmove=1;

        }

         else

           rear=rear->link;

     if (ipmove==1){

         front->link=mintime->link;

         mintime->link=ready;

    }

     ready=mintime;

 }

 void creatJCB() //为每个作业创建一个JCB并初始化形成一个循环链队列

{  

    JCB *p,*l;

    int i=0;

     l = (JCB *)malloc(sizeof(JCB));

    printf(" 请输入作业的个数:");

    scanf("%d",&N);

     printf(" 作业号No.%d: ",i);

    printf(" 请输入作业的名字:");

    scanf("%s",l->name);

    printf(" 请输入作业需要运行的时间:");

     scanf("%d",&l->need_time);

    l->state = 'r';          //作业初始状态为就绪(即准备状态)

    l->worked_time = 0;

    l->link=NULL;

     l->flag=0;

     front=l;

    for(i =1;i<N;i++)

     {

         p = (JCB *)malloc(sizeof(JCB));

        printf(" 作业号No.%d: ",i);

        printf(" 请输入作业的名字:");

        scanf("%s",p->name);

        printf(" 请输入作业的时间:");

        scanf("%d",&p->need_time);

         p->state='r';

       p->worked_time=0;

        p->flag=0;

         l->link=p;

         l=l->link;

    }

     rear=l;rear->link=front;

 } 

 void output()//进程输出函数

 { 

    int j;

    printf("name runtime needtime state ");

     for(j=1;j<=N;j++)

     {   printf(" %-4s %-4d %-4d %-c ",front->name,front->worked_time,front->need_time,front->state);

        front=front->link;

     }

    printf(" ");

 }

 int judge(JCB *p) //判断所有进程运行结束

{

     int flag=1,i;

163     for(i=0;i<N;i++)

     {

        if(p->state!='e')

        {

             flag = 0;

            break;}

        p=p->link;

    }

     return flag;

 }

 //作业输入

 void input()

 {

     int i,num;

     printf(" 请输入作业的个数:");

     scanf("%d",&num);

     for(i=0;i<num;i++)

     {

        printf(" 作业号No.%d: ",i);

         p=getpch(JCB);

        printf(" 输入作业名:");

        scanf("%s",p->name);

         printf(" 输入作业到达时刻:");

         scanf("%f",&p->arrivetime);

         printf(" 输入作业运行时间:");

        scanf("%f",&p->runtime);

       printf(" ");

         p->state='w';

        p->link=NULL;

        sort();

    }

 }

 int space()

 {

     int l=0; JCB* jr=ready;

     while(jr!=NULL)

     {

         l++;

         jr=jr->link;

     }

     return(l);

 }

 void disp(JCB* jr,int select)

 {

     if (select==3) printf(" 作业  到达时间  服务时间  响应比  运行时刻  完成时刻  周转时间  带权周转时间 ");

     else printf(" 作业 到达时间 服务时间 运行时刻 完成时刻 周转时间 带权周转时间 ");

     printf(" %s ",jr->name);

    printf("%.2f   ",jr->arrivetime);

     printf("%.2f ",jr->runtime);

    if (select==3&&p==jr) printf("   |%.2f    ",jr->Rp);

    if (p==jr){

         printf(" %.2f ",jr->wt.Tb);

        printf(" %.2f  ",jr->wt.Tc);

         printf("   %.2f ",jr->wt.Ti);

         printf("   %.2f",jr->wt.Wi);

     }

    //printf(" ");

 }

 int destroy()

 {

     free(p);

     return(1);

 }

 void check(int select)

 {

    JCB* jr;

     printf(" 是 :%s",p->name);//当前执行的作业是

     disp(p,select);

     jr=ready;

     destroy();

 }

 void running(JCB* jr)

 {

     if (T>=jr->arrivetime) jr->wt.Tb=T;

     else jr->wt.Tb=jr->arrivetime;

    jr->wt.Tc=jr->wt.Tb+jr->runtime;

     jr->wt.Ti=jr->wt.Tc-jr->arrivetime;

     jr->wt.Wi=jr->wt.Ti/jr->runtime;

     T=jr->wt.Tc;

 }

 int main()

   {

     int select=0,len,h=0;

     float sumTi=0,sumWi=0;

     printf("请选择作业调度算法的方式: ");

     printf(" 1.FCFS 2.SJF 3.HRN ");

     printf("请输入作业调度算法序号(1-3):");

     scanf("%d",&select);

     input();   //调用输入函数

    len=space();

   

    

    while((len!=0)&&(ready!=NULL))

    {

         h++;

         printf(" 第%d个执行作业 ",h);

        p=ready;

         ready=p->link;

        p->link=NULL;

         p->state='R';

         running(p);

        sumTi+=p->wt.Ti;

         sumWi+=p->wt.Wi;

        check(select); //与所选择的算法比较,调用void check(int select)

        if (select==2&&h<len-1) SJFget();

         if (select==3&&h<len-1) HRNget();

        getchar();

         getchar();

    }

    printf(" 作业已经完成. ");

    printf(" 此组作业的平均周转时间:%.2f ",sumTi/h);

    printf(" 此组作业的带权平均周转时间:%.2f ",sumWi/h);

     getchar();

}

实验结果截图:

总结与体会

通过本次实验,感觉自己对之前数据结构的算法和语法掌握得不是很好,虽然会定义结构体比较熟练,但是对于在程序中调用结构体就不太理解,导致多次出错,并通过查阅相关资料,然后不断修改,由于之前的数据结构学得不扎实,所以写代码遇到很多困难,往后要多回顾旧知识,特别是语法结构和新接触的几种作业调度的算法思想。

原文地址:https://www.cnblogs.com/huanglinsheng/p/5588053.html