zoukankan      html  css  js  c++  java
  • 1111实验二 作业调度模拟实验

    实验二、作业调度模拟实验

    物联网工程 张怡 201306104149

    一、实验目的

     (1)加深对作业调度算法的理解;

     (2)进行程序设计的训练。

     

    二、实验内容和要求

    1.至少用三种调度算法:

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

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

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

        每个作业由一个作业控制块JCB表示,JCB可以包含以下信息:作业名、提交(到达)时间、所需的运行时间、所需的资源、作业状态、链指针等等。

        作业的状态可以是等待W(Wait)、运行R(Run)和完成F(Finish)三种之一。每个作业的最初状态都是等待W。

    2. 模拟数据的生成

        1) 允许用户指定作业的个数(2-24)。

        2) 允许用户选择输入每个作业的到达时间和所需运行时间。

        3)允许用户选择通过伪随机数指定每个作业的到达时间(0-30)和所需运行时间(1-8)。

    3. 模拟程序的功能

        1) 按照模拟数据的到达时间和所需运行时间,执行FCFS, SJF和HRRN调度算法,程序计算各作业的开始执行时间,各作业的完成时间,周转时间和带权周转时间(周转系数)。

        2) 动态演示每调度一次,更新现在系统时刻,处于运行状态和等待各作业的相应信息(作业名、到达时间、所需的运行时间等)对于HRRN算法,能在每次调度时显示各作业的响应比R情况。

     

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

    1. 源程序名:压缩包文件(rarzip)中源程序名ZuoYeDiaoDu.c

    可执行程序名:ZuoYeDiaoDu.exe

    2. 原理分析及流程图

          这个程序主要是对三种作业调度算法的使用,主程序里是两个界面菜单和调度算法程序的调用。menu1是初始界面,提示是进入“用户输入数据模式”、“随机数制定数据模式”,还是要退出程序。若选择1,则提示“请输入作业个数(2~24):”,输入作业个数后提示输入“作业名称提交时刻运行时间”,输入完毕后打印用户刚输入的原始数据,并提示四个选项,用户可选择任意一项,若输入1~3之中的任意一个,则进入该数字对应的作业调度算法,若输入4则返回初始界面。

          进入作业调度算法后,提示按Enter键继续作业,并打印“当前时间”、“还未进入后备队列的作业”、“进入后备队列的作业”以及“处于运行的作业”。最后打印“已经完成的作业”,按Enter键打印“平均周转时间”和“平均周转系数”,并提示四个选项,用户可选择1~3继续进行作业调度,或者选择4返回初始界面。

           

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

    #include <stdio.h>

    #include <stdlib.h>

    #include <string.h>

    #include <time.h>

    #define MAX 24

    typedef struct job

    {

           char jname[10];//作业名

        int arrivetime;//提交时间

           int actiontime;//执行时间

           int stime;//开始时间

           int etime;//完成时间

           int zztime;//周转时间

           float zzxs;//周转系数         

    }JOB;

    JOB job[MAX],HBjob[MAX];

    JOB temp;

    float ave_zztime=0,ave_zzxs=0; //平均周转时间和周转系数

    int num=5;

    void input()

    {    int i=0;

           system("cls");//清屏 , system()函数是调用dos命令. cls是dos命令中的清屏命令clear screen的简写

           printf("请输入作业个数(2-24):");

           scanf("%d",&num);

           while(num<2&&num>24)

           {    printf(" 请重新输入作业个数(2~24):");

                  scanf("%d",&num);

           }

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

           {    printf(" 请输入第%d个数作业的名称:",i+1);

                  scanf("%s",job[i].jname);

                  printf(" 请输入第%d个作业的提交时刻:",i+1);

                  scanf("%d",&job[i].arrivetime);

                  printf(" 请输入第%d个作业的运行时间:",i+1);

                  scanf("%d",&job[i].actiontime);

           }

           system("cls");

           printf(" 用户输入的原始数据 ");

           printf(" 作业名称 提交时刻 运行时间 ");

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

           {    printf("   %s   %d   %d",job[i].jname,job[i].arrivetime,job[i].actiontime);

                  printf(" ");

           }     

    }

    void paixu()

    {

           int i,j;

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

           {

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

                  {

                         if(job[j].arrivetime>job[j+1].arrivetime)

                         {

                                temp=job[j];

                                job[j]=job[j+1];

                                job[j+1]=temp;

                         }

                  }

           }

           printf("按提交时间排序后,还未进入后备队列的任务! ");

           printf("作业名称 提交时刻 运行时间 ");

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

           {

                  printf("  %s   %d   %d",job[i].jname,job[i].arrivetime,job[i].actiontime);

                  printf(" ");

           }  

    }

    void jisuan()

    {

           int i;

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

           {

                  if(i==0)

                  {

                         job[i].stime=job[i].arrivetime;

                         job[i].etime=job[i].arrivetime+job[i].actiontime;

                  }

                  else if(job[i-1].etime<=job[i].arrivetime)//上一作业的完成时间<=本次作业的提交时间

                  {

                         job[i].stime=job[i].arrivetime;

                         job[i].etime=job[i].arrivetime+job[i].actiontime;

                  }

                  else

                  {

                         job[i].stime=job[i-1].etime;

                         job[i].etime=job[i].stime+job[i].actiontime;

                  }

           }

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

           {

                  job[i].zztime=job[i].etime-job[i].arrivetime;//周转时间=完成时间-提交时间

                  job[i].zzxs=(float)job[i].zztime/job[i].actiontime;//周转系数=周转时间/执行时间

           }

    }

    void FCFS()

    {

           int i,j,k,l,time=0;

          

           printf(" 按先来先服务优先调度算法进行调度! ");

           paixu();   

           jisuan();

           i=0;

           while(1)

           {

                  if(i==num)

                  {

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

                         {

                                ave_zztime+=job[l].zztime;

                         }

                         ave_zztime=ave_zztime/num;       //平均周转时间=周转时间总和/作业个数

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

                         {

                                ave_zzxs+=job[l].zzxs;

                         }

                         ave_zzxs/=num;

                         printf("平均周转时间为:%.2f",ave_zztime);

                         printf(" 平均周转系数为:%.2f ",ave_zzxs);

                         break;

                         break;

                  }

                  printf(" 当前系统时间为:%d ",time);

                  if(time>=job[i].arrivetime)

                  {     

                         printf("还未进入后备队列的作业! ");

                         printf("作业名称 提交时刻 运行时间 ");

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

                         {

                                if(time<job[j].arrivetime)

                                {

                                printf("  %s   %d   %d ",job[j].jname,job[j].arrivetime,job[j].actiontime);

                                }

                         }

                         if(time<job[num-1].arrivetime)

                         {    printf(" 进入后备队列的作业! ");

                                printf("作业名称 提交时刻 运行时间 ");

                                for(k=num-1;k>=i;k--)

                                {

                                if(time>=job[k].arrivetime)

                                { printf("  %s   %d %d ",job[k].jname,job[k].arrivetime,job[k].actiontime);

                                       }

                                }

                         }

                         printf(" 处于运行的作业为:%s ",job[i].jname);

                         printf("已经完成的作业! ");

                        

                         printf("作业名称 提交时刻 运行时间 开始时刻 完成时刻 周转时间 周转系数 ");

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

                         {

                                printf("%5s   %3d    %3d    %3d     %3d      %3d %.2f ",job[k].jname,job[k].arrivetime,job[k].actiontime,job[k].stime,job[k].etime,job[k].zztime,job[k].zzxs);

                         }

                         time=time+job[i].actiontime;

                         i++;

                         printf(" 请按Enter键继续...");

                         fflush(stdin);         

                         getchar();

                  }

                  else

                  {

                         time++;

                         printf(" 请按Enter键继续...");

                         fflush(stdin);         

                         getchar();

                  }

                 

           }

    }

    void SJF()

    {

           int i,j,k,l=0,time=0;

          

           paixu();

           printf("按短作业优先调度算法进行调度! ");

           i=0;

           while(1)

           {

                  if(i==num)

                  {

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

                         {

                                ave_zztime+=job[l].zztime;

                         }

                         ave_zztime/=num;

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

                         {

                                ave_zzxs+=job[l].zzxs;

                         }

                         ave_zzxs/=num;

                         printf("平均周转时间为:%.2f",ave_zztime);

                         printf(" 平均周转系数为:%.2f ",ave_zzxs);

                         break;

                  }     

                  printf(" 当前系统时间为:%d ",time);

                  printf(" 请按Enter键继续...");

                  fflush(stdin);         

                  getchar();

                  if(time>=job[i].arrivetime)

                  {

                         printf("还未进入后备队列的作业! ");

                         printf("作业名称 提交时刻 运行时间 ");

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

                         {

                                if(time<job[j].arrivetime)

                                {

                                      

                                printf("  %s   %d   %d ",job[j].jname,job[j].arrivetime,job[j].actiontime);

                                }

                         }

                         for(j=i;j<num-1;j++)

                         {

                                for(k=i;k<num-1;k++)

                                {

                                if((job[k].actiontime>job[k+1].actiontime)&& (time>=job[k].arrivetime)&& (time>=job[k+1].arrivetime))

                                       {

                                              temp=job[k];

                                              job[k]=job[k+1];

                                              job[k+1]=temp;

                                       }

                                }     

                         }

                         printf(" 进入后备队列的作业! ");

                         printf("作业名称 提交时刻 运行时间 ");

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

                         {

                                if(time>=job[k].arrivetime)

                                {

                                printf("  %s   %d %d ",job[k].jname,job[k].arrivetime,job[k].actiontime);

                                }

                         }     

                         jisuan();

                         printf(" 处于运行的作业为:%s ",job[i].jname);

                         printf("已经完成的作业! ");

                         printf("作业名称 提交时刻 运行时间 开始时刻 完成时刻 周转时间 周转系数 ");

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

                         {

                                printf("%5s   %3d    %3d    %3d     %3d      %3d %.2f ",job[k].jname,job[k].arrivetime,job[k].actiontime,job[k].stime,job[k].etime,job[k].zztime,job[k].zzxs);

                         }

                         time=time+job[i].actiontime;

                        

                         printf(" 请按Enter键继续...");

                         fflush(stdin);         

                         getchar();

                         i++;

                  }

                  else

                  {

                         time++;

                         printf(" 请按Enter键继续...");

                         fflush(stdin);         

                         getchar();

                  }     

           }     

    }

    void HRRF()

    {

           int i,j,k,l=0,time=0;

           float max=0;

           printf(" 按响应比优先调度算法进行调度! ");

           paixu();

           i=0;

           while(1)

           {

                  if(i==num)

                  {

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

                         {

                                ave_zztime+=job[l].zztime;

                         }

                         ave_zztime/=num;

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

                         {

                                ave_zzxs+=job[l].zzxs;

                         }

                         ave_zzxs/=num;

                         printf("平均周转时间为:%.2f",ave_zztime);

                         printf(" 平均周转系数为:%.2f ",ave_zzxs);

                         break;

                         break;

                  }     

                  printf(" 当前系统时间为:%d ",time);

                  printf(" 请按Enter键继续...");

                  fflush(stdin);         

                  getchar();

                  if(time>=job[i].arrivetime)

                  {

                         printf("还未进入后备队列的作业! ");

                         printf("作业名称 提交时刻 运行时间 ");

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

                         {

                                if(time<job[j].arrivetime)

                                {

                                      

                                printf("  %s   %d   %d ",job[j].jname,job[j].arrivetime,job[j].actiontime);

                                }

                         }

                         if(i==0)

                         {

                                jisuan();

                         }

                         else{

                                jisuan();

                                for(j=i;j<num-1;j++)

                                {

                                       for(k=i;k<num-1;k++)

                                       {

                                              max=(float)(job[k-1].etime-job[k].arrivetime+job[k].actiontime)/job[k].actiontime;

                                              if(max<(float)(job[k].etime-job[k+1].arrivetime+job[k+1].actiontime)/job[k+1].actiontime && (time>=job[k].arrivetime)&&(time>=job[k+1].arrivetime))

                                              {

                                                     temp=job[k];

                                                     job[k]=job[k+1];

                                                     job[k+1]=temp;

                                              }

                                       }     

                                }

                         }

                         printf(" 进入后备队列的作业! ");

                         printf("作业名称 提交时刻 运行时间 ");

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

                         {

                                if(time>=job[k].arrivetime){

                         printf("  %s   %d   %d ",job[k].jname,job[k].arrivetime,job[k].actiontime);

                                }

                         }     

                         printf(" 处于运行的作业为:%s ",job[i].jname);

                         printf("已经完成的作业! ");

                         printf("作业名称 提交时刻 运行时间 开始时刻 完成时刻 周转时间 周转系数 ");

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

                         {

                                printf("%5s   %3d    %3d    %3d     %3d      %3d %.2f ",job[k].jname,job[k].arrivetime,job[k].actiontime,job[k].stime,job[k].etime,job[k].zztime,job[k].zzxs);

                         }

                         time=time+job[i].actiontime;

                         printf(" 请按Enter键继续...");

                         fflush(stdin);         

                         getchar();

                         i++;

                  }

                  else

                  {    time++;

                         printf(" 请按Enter键继续...");

                         fflush(stdin);         

                         getchar();

                  }

           }

    }

    int menu2()

    {    int chioce;

           printf(" 1.先来先服务(FCFS)调度算法 ");

           printf(" 2.短作业优先(SJF) 调度算法 ");

           printf(" 3.响应比优先(HRRF)调度算法 ");

           printf(" 4.返回上一层 ");

           printf(" 请选择:");

           scanf("%d",&chioce);

           return chioce;

          

    }

    void suiji()

    {

           int i=0,j=0;

           system("cls");

           printf("请输入作业个数(2-24):");

           scanf("%d",&num);

           while(num<2&&num>24)

           {    printf(" 请重新输入作业个数(2~24):");

                  scanf("%d",&num);

           }

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

           {    itoa(i+1,job[i].jname,10);

                  job[i].arrivetime=rand()%10+1;

                  job[i].actiontime=rand()%10+1;

           }

           system("cls");

           printf(" 用户输入的原始数据 ");

           printf(" 作业名称 提交时刻 运行时间 ");

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

           {    printf("   %s   %d   %d",job[i].jname,job[i].arrivetime,job[i].actiontime);

                  printf(" ");

           }

    }

    int menu1()

    {

           int choice;

           do{

                  printf(" --------------------------------------------------------- ");

                  printf(" 1.用户输入数据模式 ");

                  printf(" 2.随机数指定数据模式 ");

                  printf(" 3.退出 ");

                  printf(" --------------------------------------------------------- ");

                  printf(" 请选择: ");

                  scanf("%d",&choice);

                  getchar();

                  if(choice<0||choice>3)

                  {    printf("输入有错!!!请重新选择!");

                         scanf("%d",&choice);

                         getchar();

                  }

           }while(choice<0||choice>3);

           return choice;

    }

    main()

    {    int chioce1=0,chioce2=0;

           while(1)

           {FH:  system("cls");//清屏

                  chioce1=menu1();

                  switch(chioce1)

                  {

                  case 1:

                         {

                                input();

                                break;

                         }

                  case 2:

                         {

                                suiji();

                                break;

                         }

                  case 3:

                         {

                                printf(" 谢谢使用!!! ");

                                exit(0);//正常运行程序并退出程序;

                         }

                  }

                  while(1){

                         chioce2=menu2();

                         switch(chioce2){

                         case 1:

                                { 

                         FCFS();//先来先服务

                                   break;

                                }

                         case 2:

                                {

                                       SJF();//短作业优先

                                       break;

                                }

                         case 3:

                                {

                                       HRRF();//响应比优先

                                       break;

                                }

                         case 4:

                                {

                                       goto FH;//回到开始界面

                                }

                         }

                  }

           }     

    }

     

    4. 运行结果及分析

          运行程序,有如下效果:显示菜单选项并提示“请选择:”。输入“1”跳入“用户输入数据模式”,输入“2”跳入“随机数指定数据模式”。输入“3”则退出该程序。  “随机数指定数据模式”只需输入作业个数,其他数据由随机数组成。

     

         “用户输入数据模式”需要用户自己输入数据,可选择要输入的数据组数(2~24)。

     

          随后提示输入“作业名称 提交时刻 运行时间”,输入完毕后显示输入的数据。此时可选择调度算法,输入“1”则进行先来先服务调度,输入“2”进行短作业优先调度,输入“3”进行响应比优先调度,输入“4”则返回上一层。提示“请选择:”。

    输入选项后显示如下:(按“Enter”键继续进行调度)

     

          调度过程中打印已完成的作业和等待中的作业,完成后打印各组作业的“作业名称 提交时刻 运行时间 开始时刻 完成时刻 周转时间 周转系数”。 作业调度完成后可选择下图四个选项中的其中一个,使程序继续进行作业调度或者返回到初始页面。

     

        

    四、实验总结

          这次的实验主要是看我们对作业调度算法的熟悉程度,开始的时候对算法不够了解,因此进度很慢,经过上网查资料问同学后加深了对算法的了解。先做了个程序框架,将需要用到的算法公式和要用到的参数列出来,将然后写成代码。为了使页面美观,初始界面输入选项后和跳回初始界面时进行清屏操作。此外,每次完成输入后都会把用户输入原始数据一起打印出来,调动完成后也会按照先后顺序把已完成的作业信息一起打印出来,方便观察。最后计算出“平均周转时间”和“平均周转系数”并打印出来,然后提示四个选项,用户可选择继续进行作业调度或返回到初始界面。

  • 相关阅读:
    Leetcode 50.Pow(x,n) By Python
    Leetcode 347.前K个高频元素 By Python
    Leetcode 414.Fizz Buzz By Python
    Leetcode 237.删除链表中的节点 By Python
    Leetcode 20.有效的括号 By Python
    Leetcode 70.爬楼梯 By Python
    Leetcode 190.颠倒二进制位 By Python
    团体程序设计天梯赛 L1-034. 点赞
    Wannafly挑战赛9 C-列一列
    TZOJ Start
  • 原文地址:https://www.cnblogs.com/zy1717/p/4957557.html
Copyright © 2011-2022 走看看