• 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”键继续进行调度)

     

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

     

        

    四、实验总结

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

  • 相关阅读:
    zabbix实现mysql数据库的监控(四)
    Redis高级进阶(一)
    Redis高级进阶(二)
    Redis的管理
    9.动态SQL
    8.Mapper动态代理
    7.属性名与查询字段名不相同
    6.单表的CRUD操作
    5.API详解
    4.主配置文件详解
  • 原文地址:https://www.cnblogs.com/zy1717/p/4957557.html
Copyright © 2020-2023  润新知