欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

操作系统实验报告二 作业调度-代码阅读并调试实验

程序员文章站 2022-07-05 11:05:45
...

实验二 作业管理

任务一

一、实验名称

       作业调度-代码阅读并调试实验

二、实验目的

1.阅读下面源代码,完善程序空白处内容。
2.阅读代码,写出源程序采用什么调度算法、算法流程图和程序功能。
3.解释作业控制块构JCB的定义和作用。
4.为main()写出每行的注释。
5.调试并运行代码,写出结果。

作业调度源程序如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#define getpch(type) (type*)malloc(sizeof(type))
int n;
float T1=0,T2=0;
int times=0;  
   
struct jcb      //作业控制块
{  
    char name[10];  //作业名 
    int reachtime;   //作业到达时间
    int starttime;    //作业开始时间
    int needtime;       //作业运行所需时间 
    int finishtime;       //作业完成时间 
    float cycletime;       //作业周转时间 
    float cltime;           //带权周转时间
    char state;            //作业状态
    struct jcb *next;      //结构体指针
}*ready=NULL,*p,*q;
   
typedef struct jcb JCB;
   
void inital()   //建立作业控制块队列,先将其排成先来先服务的模式队列
{
    int i;
    printf("\n输入作业数:");
    scanf("%d", &n);
    for (i = 0; i<n; i++)   
    {
        p = getpch(JCB);      
        printf("\n输入作业名:");        
        scanf("%s", p->name);     
        getchar();       
        p->reachtime = i;      
        printf("作业默认到达时间:%d", i);     
        printf("\n输入作业要运行的时间:");     
        scanf("%d", &p->needtime);   
        p->state = 'W';   
        p->next = NULL;      
        if (ready == NULL) 
        ready = q = p;     
        else
        {
                q->next = p;       
                q = p;
        }
    }
}
   
void disp(JCB*q,int m) //显示作业运行后的周转时间及带权周转时间等
{
    printf("\n作业%s正在运行,估计其运行情况:\n",q->name);  
    printf("开始运行时刻:%d\n",q->starttime);   
    printf("完成时刻:%d\n",q->finishtime);
    printf("周转时间:%f\n",q->cycletime); 
    printf("带权周转时间:%f\n",q->cltime);  
    getchar(); 
}
   
void running(JCB *p, int m)  //运行作业
{
    if (p == ready)     //先将要运行的作业从队列中分离出来
    {
    ready = p->next;
    p->next = NULL;
    }
    else
    {
        q = ready;
        while (q->next != p)  q = q->next;
        q->next = p->next;
    }
    p->starttime = times;    //计算作业运行后的完成时间,周转时间等等
    p->state = 'R';
    p->finishtime = p->starttime + p->needtime;
    p->cycletime = (float)(p->finishtime - p->reachtime);
    p->cltime = (float)(p->cycletime / p->needtime);
    T1 += p->cycletime;
    T2 += p->cltime;
    disp(p, m);        //调用disp()函数,显示作业运行情况    
    times += p->needtime;
    p->state = 'F';
    printf("\n%s has been finished!\n", p->name);
    free(p);          //释放运行后的作业
    getchar();
}
   
void final() //最后打印作业的平均周转时间,平均带权周转时间
{   
    float s,t;  
    t=T1/n; 
    s=T2/n;  
    getchar();  
    printf("\n\n作业已经全部完成!\n");  
    printf("\n%d个作业的平均周转时间是:%f",n,t);  
    printf("\n%d个作业的平均带权周转时间是%f:\n\n\n",n,s);
}
  
void sjf(int m)      // 最短作业优先算法
{    
    JCB *min; 
    int i,iden; 
    system("cls");   
    inital();  
    for(i=0;i<n;i++)
    {         
        p=min=ready;
        iden=1; 
        do{      
                if(p->state=='W'&&p->reachtime<=times)    
                if(iden)
                {                 
                    min=p;
                    iden=0;   
                }             
                else if(p->needtime<min->needtime) min=p;         
                 p=p->next ; // 1 根据上下文,空格处填写一条指令   
            } while (p != NULL);
        if(iden)
        {       
            i--; 
            times++;     
            if (times>100)
            {
             printf("\nruntime is too long … error");
             getchar();
            }
        }
        else
        {
            running(min, m);     
        }   
    }   
    final();     
}
  
void fcfs(int m)     //先来先服务算法
{
  
    int i, iden;  
    system("cls");   
    inital();    
    for (i = 0; i<n; i++) 
    {
  
        p = ready;
        iden = 1;   
        do {
            if (p->state == 'W'&&p->reachtime <= times)  iden = 0;         
            if (iden)p = p->next;
        } while (p != NULL&&iden);
  
       if (iden)          
        {
            i--;    
            printf("\n没有满足要求的进程,需等待");
        
             times++ ; // 2根据上下文,填入一条语句
        
            if (times>100)
            {
               printf("\n时间过长");
               getchar();
            }
        }
        else
        {
            running(p, m); 
        }    
    }  
    final();     
}
  
void menu()
{
    int m;  
    system("cls");                   <br>    printf("\n\n\t\t*********************************************\t\t\n");
    printf("\t\t\t\t作业调度演示\n"); 
    printf("\t\t*********************************************\t\t\n"); 
    printf("\n\n\n\t\t\t1.先来先服务算法.");
    printf("\n\t\t\t2.最短作业优先算法.");
    printf("\n\t\t\t0.退出程序."); 
    printf("\n\n\t\t\t\t选择所要操作:");
    scanf("%d", &m);
    switch (m) 
    {
    case 1:     
        fcfs(m); 
        getchar();     
        system("cls"); 
        break; 
    case 2:  
        sjf(m);  
        getchar();   
        system("cls");    
        break;   
        case 0:  
        system("cls");
        break; 
        default:  
        printf("选择错误,重新选择."); 
        getchar();      
        system("cls");  
        menu();
    }
}
int main()
{      
    menu();//调用menu函数
    system("pause");//暂停
    return 0;//结束
} 

三、实验过程

1.阅读下面源代码,完善程序空白处内容。
已在上文作业调度源程序呈现

2.阅读代码,写出源程序采用什么调度算法、算法流程图和程序功能。
(1)调度算法
先来先服务调度算法和短作业优先调度算法
(2)算法流程图
先来先服务调度算法

短作业优先调度算法

(3)程序功能
模拟了先来先服务调度算法和短作业优先调度算法的调度作业的过程

3.解释作业控制块构JCB的定义和作用。
(1)定义
JCB是作业在系统中存在的唯一标志,其中保存了系统对作业进行管理和调度所需的全部信息。作业控制块包括:作业名、作业类型、资源要求、当前状态、资源使用情况以及该作业的优先级等。
(2)作用
在多道批处理系统中,为了管理和调度作业,操作系统通过JCB了解到作业要求,并分配资源和控制作业中程序和数据的编译、链接、装入和执行等。

4.为main()写出每行的注释。
已在上文作业调度源程序呈现

5.调试并运行代码,写出结果。
(1)先来先服务调度算法运行结果
……
(2)短作业优先调度算法运行结果
……

四、实验总结

……
……

任务二

一、实验名称

     作业调度-设计测试实验

二、实验目的

1、编写并调试一个单道系统的作业调度模拟程序。
调度模型:描述调度模型。(可以采用模块化方法并用框图说明)
作业调度算法:分别采用先来先服务(FCFS),最短作业优先(SJF)、响应比高者优先(HRN)的调度算法。
要求:
1) 定义JCB,并操作之。
2) 描述作业队列。
3) 对每种调度算法都要求打印每个作业开始运行时刻、完成时刻、周转时间、带权周转时间,以及这组作业的平均周转时间及带权平均周转时间,以比较各种算法的优缺点。  
2、编写并调试一个多道系统的作业调度模拟程序。
调度模型:描述多道调度模型。(可以采用模块化方法并用框图说明)
作业调度算法:先来先服务(FCFS)
要求:
1) 定义JCB,并操作之。
2) 描述作业队列。
3) 定义多道系统中的各种资源种类及数量、调度作业时必须考虑到每个作业的资源要求。

3、编写并调试一个多道系统的作业调度模拟程序。
调度模型:描述多道调度模型。(可以采用模块化方法并用框图说明)
作业调度算法:采用基于优先级的作业调度。
要求:
1)自己设计一个确定优先级的方法。
2) 定义JCB,并操作之。
3)描述作业队列。4)定义多道系统中的各种资源种类及数量、调度作业时必须考虑到每个作业的资源要求。

三、实验过程

1、编写并调试一个单道系统的作业调度模拟程序。

(1)定义JCB如下。包括作业名、抵达时间、开始运行时刻、运行所需时间、完成时刻、周转时间、带权周转时间、状态和响应比等。

struct jcb
{
    char name[10];//用户名称
    int reachtime;//作业抵达时间
    int starttime;//作业开始时间
    int needtime;//作业运行所需时间
    int finishtime;//作业完成时间
    float cycletime;//作业周转时间
    float cltime;//带权周转时间
    char state;//作业状态
    struct jcb *next;//结构体指针
    int Rp;//响应比——响应时间/要求服务时间
    int waittime;//等待时间
}

(2)描述作业队列。
先来先服务(FCFS)的作业队列是按作业到达的先后顺序排列的;
最短作业优先(SJF)的作业队列是按作业由长到短的顺序排列的;
响应比高者优先(HRN)的作业队列是按照响应比由高到低的顺序排列的;

(3)对每种调度算法都要求打印每个作业开始运行时刻、完成时刻、周转时间、带权周转时间,以及这组作业的平均周转时间及带权平均周转时间,以比较各种算法的优缺点。

2、编写并调试一个多道系统的作业调度模拟程序。

2、(1) 定义JCB如下:

struct jcb      //作业控制块
{
    char name[10];  
    int reachtime;  
    int rnum;       //作业所需资源的种类数
    int starttime;  
    int needtime;
    int finishtime; 
    float cycletime;
    float cltime;   //带权周转时间
    char state;  
    int IsUsed;    //标志是否使用该资源
    resource *res;  //所需资源指针
    struct jcb *next;      //结构体指针
}*ready[4], *p, *q; 

(2) 描述作业队列。
作业队列是按作业到达的先后顺序排列的。

(3) 定义多道系统中的各种资源种类及数量、调度作业时必须考虑到每个作业的资源要求。

3、编写并调试一个多道系统的作业调度模拟程序。

1)自己设计一个确定优先级的方法。
基于优先级的作业调度

2) 定义JCB如下:

struct JCB
{
   string ID;                                       
   int priority;                                           
   double begin_time;                             
   double rtime;                                  
   double turnaround_time;                      
   double cpu_service_time;                       
   double io_time;                             
   double finish_time;                             
   double Wturnaround_time;                      
   JCB& operator = (const JCB& p2)              
   {
       this->priority = p2.priority;
       this->begin_time = p2.begin_time;
       this->rtime = p2.rtime;
       this->finish_time = p2.finish_time;
       this->cpu_service_time = p2.cpu_service_time;
       this->io_time = p2.io_time;
       this->ID = p2.ID;
       this->turnaround_time = p2.turnaround_time;
       this->Wturnaround_time = p2.Wturnaround_time;
       return *this;
   }
};

3)描述作业队列
作业队列是按作业优先级顺序排列的。

四、实验总结

……

五、代码

1、单道系统的作业调度模拟程序
#include<stdio.h>
#include<stdlib.h>
#define N 5

struct jcb
{
    char name[10];//用户名称
    int reachtime;//作业抵达时间
    int starttime;//作业开始时间
    int needtime;//作业运行所需时间
    int finishtime;//作业完成时间
    float cycletime;//作业周转时间
    float cltime;//带权周转时间
    char state;//作业状态
    struct jcb *next;//结构体指针
    int Rp;//响应比——响应时间/要求服务时间
    int waittime;//等待时间
}*ready = NULL, *p, *q;

int main()

{
         int a[2][5]={0};  //a[0][i]存放到达的时间,a[1][i]存放需要的服务时间

         int d[5]={0};

         int h[5]={0,1,2,3,4};

         double b[4][6]={0};  //FCFS

         double n[4][6]={0};  //SJF

         double m[4][6]={0};  //最高相应比优先

         double c[5];    //存放响应比

         double ha[5];   //存放服务时间用于响应比排序

         int i=0,j=0,t;

         int temp;

         int r,z;

         printf("五个进程:\tA\tB\tC\tD\tE\n");

   printf("到达时间:\t");

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

         {

                   a[0][i]=i;     //到达时间

                   printf("%d\t",a[0][i]);

         }

         printf("\n");

         printf("请输入服务时间:\t");

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

         {
             scanf("%d",&a[1][i]);  //服务时间

         }

         printf("服务时间:\t");

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

         {

                    d[i]=a[1][i];    //把服务时间顺便存放到d数组中

                  printf("%d\t",a[1][i]);

         }

         printf("\n");

   /*先来先服务*/

   printf("FCFS\n");

   printf("开始时间:\t");

         b[0][0]=a[0][0];

                   printf("%d\t",b[0][0]);

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

    {
           b[0][i]=b[0][i-1]+(double)(a[1][i-1]);

     printf("%d\t",(int)b[0][i]);//b[0][i]存放的是各进程开始时间

         }

         printf("\n");

         b[1][0]=(double)a[1][0];

   printf("完成时间:\t%d\t",(int)b[1][0]); //b[1][i]存放的是完成时间

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

    {
           b[1][i]=b[0][i]+(double)a[1][i];

     printf("%d\t",(int)b[1][i]);

         }

         printf("\n");

   printf("周转时间:\t");

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

    {
     b[2][i]=b[1][i]-(double)a[0][i];

           b[2][5]+=b[2][i];   //b[2][5]周转时间累加和

     printf("%d\t",(int)b[2][i]); //b[2][i]存放的是周转时间

         }

         printf("arve=%.2f\n",b[2][5]/5);

         printf("带权周转时间:\t");

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

    {
           b[3][i]=b[2][i]/(double)(a[1][i]);

           b[3][5]+=b[3][i];  //b[3][5]带权周转时间累加和

     printf("%.1f\t",(double)b[3][i]);//b[3][i]存放的是带权周转时间

         }

         printf("avre=%.2f\n",b[3][5]/5);

   /*短作业优先*/

   printf("SJF\n");

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

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

                            if(d[i]>d[j])

                            {
                              t=d[j];

                              d[j]=d[i];

                              d[i]=t;



                              temp=h[j];

                              h[j]=h[i];

                              h[i]=temp;

                            }                //h[i]即为进程服务的顺序   for(i=0;i<5;i++)printf("%d\t",h[i]);

         printf("开始时间:\t");

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

         {
                   n[0][h[i]]=a[1][h[i-1]]+n[0][h[i-1]];

         }

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

           printf("%d\t",(int)n[0][i]);

     printf("\n");

         printf("完成时间:\t");

         n[1][0]=a[1][0];

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

            n[1][h[i]]=n[0][h[i]]+a[1][h[i]];

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

           printf("%d\t",(int)n[1][i]);

     printf("\n");

       printf("周转时间:\t");

         //n[2][0]=n[1][0]-a[0][0];//刚开始总是先执行第一个来的

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

            n[2][i]=n[1][i]-a[0][i];

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

         {
           n[2][5]+=n[2][i];  //总周转时间

           printf("%d\t",(int)n[2][i]);

    }

     printf("avre=%.2f\n",n[2][5]/5);

   printf("带权周转时间\t");

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

            n[3][i]=n[2][i]/a[1][i];

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

  {

            n[3][5]+=n[3][i];  //总带权周转时间

            printf("%.1f\t",n[3][i]);

   }

     printf("avre=%.2f\n",n[3][5]/5);

   /*最高相应比优先*/

   printf("最高相应比优先:\n");

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

       {
          ha[i]=a[1][i];//a[1][i]服务时间,ha[i]用于排序找响应比

        }

      m[0][0]=0;  //开始时间

      m[1][0]=a[1][0];

      r=0;

     for(int X=1;X<N;X++)

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

         {
              if(ha[i]!=0)

                 c[i]=1+(double)(m[1][r]-a[0][i])/a[1][i];//c[i]用于存放响应比

           else

              c[i]=0;

         }

                  z=1;

               for(j=1;j<N;j++) //选出每次最高的响应比

                     {
                 if(c[z]<=c[j]&&ha[j]!=0)

                  z=j;

                     }

                 ha[z]=0;

                 m[0][z]=m[1][r];

                 m[1][z]=m[0][z]+a[1][z];

                 r=z;

           }

              printf("开始时间:\t");

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

             printf("%d\t",(int)m[0][i]);

                    printf("\n");

        printf("完成时间:\t");

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

             printf("%d\t",(int)m[1][i]);

        printf("\n");

                    printf("周转时间\t");

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

                    {
                             m[2][i]=m[1][i]-a[0][i];

                             m[2][5]+=m[2][i];  //m[2][5]周转时间累加和

                             printf("%d\t",(int)m[2][i]);

                    }

                    printf("aver=%.2f\n",m[2][5]/5);

                    printf("带权周转时间\t");

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

                    {
                             m[3][i]=m[2][i]/a[1][i];

                             m[3][5]+=m[3][i];

                             printf("%.1f\t",m[3][i]);

                    }

                    printf("aver:%.2f\n",m[3][5]/5);

}
2、多道系统的作业调度模拟程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define getpch(type) (type*)malloc(sizeof(type))
#define NUM_OF_RESOURCE 3
struct Resource
{
    char name[10];//资c源名
    int num;      //资源的数量
    int usedTime; //作业该资源耗时
    struct Resource *link;
};
typedef struct Resource resource;
struct jcb      //作业控制块
{
    char name[10];  // 作业名
    int reachtime;  //作业到达时间
    int rnum;       //作业所需资源的种类数
    int starttime;  //作业开始时间
    int needtime;
    int finishtime; //作业完成时间
    float cycletime;//作业周转时间
    float cltime;   //带权周转时间
    char state;     //作业状态
    int IsUsed;    //标志是否使用该资源
    resource *res;  //所需资源指针
    struct jcb *next;      //结构体指针
}*ready[4], *p, *q; //q用来指向当前节点
//创建四个队列,依次对应三种资源的就绪队列

int times  = 0;
typedef struct jcb JCB;

//资源插入作业
void InsertR ( JCB *p, resource *ptr )
{
    if ( p -> res == NULL )
    {
        p->res = ptr;
    }
    else
    {
        resource* pt = p -> res;
        while ( pt->link != NULL )
            pt = pt->link;
        pt -> link = ptr;
    }
}

//作业进入就绪队列,并根据到达时间进行排序
void InsertJobs ( JCB* p, int t )
{
    if ( ready[t] == NULL )
        ready[t] = p;
    else
    {
        JCB *pt = ready[t];
        q = pt->next;
        //比队首元素来得早,就待在队首
        if ( pt->reachtime > p->reachtime )
        {
            ready[t] = p;
            p->next = pt;
        }
        else
        {
            while ( q != NULL && q->reachtime <= p->reachtime )
            {
                pt = pt->next;
                q = pt->next;
            }
            if ( q == NULL )
            {
                pt->next = p;
            }
            else
            {
                pt->next = p;
                p->next = q;
            }
        }

    }
}
//输入m个作业
void init ( int m )
{
    resource *ptr;
    int i, j;
    printf ( "请输入作业数" );
    printf ( "%d \n", m );
    for ( i = 0; i < m; i++ )
    {
        p = getpch ( JCB );
        //
        printf ( "输入作业名: " );
        scanf ( "%s", p->name );
        printf ( "\n输入作业到达时间" );
        scanf ( "%d", &p->reachtime );
        printf ( "\n输入作业所需资源的种类数:" );
        scanf ( "%d", &p->rnum );
        p->res = NULL;
        for ( j = 0; j < p->rnum; j++ )
        {
            ptr = ( resource* ) malloc ( sizeof ( resource ) );
            printf ( "\n\t输入资源名: " );
            scanf ( "%s", ptr->name );
            printf ( "\n\t输入所需资源的数量: " );
            scanf ( "%d", &ptr->num );
            printf ( "\n\t输入该作业消耗该资源的时间: " );
            scanf ( "%d", &ptr->usedTime );
            p->IsUsed = 1; //默认都使用
            ptr->link = NULL;
            InsertR ( p, ptr );
        }
        p->state = 'W';//W表示就绪状态
        p->next = NULL;
        InsertJobs   ( p, 0 ); //把p插入后备队列
    }
}
void Running(JCB *p, int j, resource *cre)
{
    printf("%s的调度结果:\n", cre[j].name);
    printf("作业名为:%s\n", p->name);
    printf("到达该资源的时间:%d\n", p->reachtime);
    p->reachtime = p->starttime+p->needtime;
    printf("释放该资源的时间%d\n",p->reachtime);
    InsertJobs(p, j+1);
}
//调度算法
void FCFS ( resource *cre )
{
    int j = 0;
    for ( j = 0; j < 3; j++ )
    {
        printf ( "\n" );
        p = ready[j];
        if ( p != NULL )
        {
            ready[j] = p->next;
            p->next = NULL;//脱离原队列
        }
        while ( p != NULL )
        {
            //寻找p中所含的资源数
            resource * ptr = p->res;
            while ( ptr != NULL && strcmp ( ptr->name, cre[j].name ) )
            {
                ptr = ptr->link;
            }
            //作业需要该资源数量目小于等于现存资源数或不需要该资源,则执行p
            if ( ptr != NULL && ptr->num <= cre[j].num )
            {
                //如果当前时刻小于到达时刻,则当前时刻应当到到达时刻才能运行
                if ( times <= p->reachtime )
                {
                    times = p->reachtime;
                }
                if ( ptr == NULL )
                {
                    p->starttime = times;
                    p->needtime = 0;
                    p->IsUsed = 0; //标志为不需要该资源
                    Running ( p, j, cre );
                }
                //需要该资源则应从系统资源中减去所需的数目
                else
                {
                    p->starttime = times;
                    p->needtime = ptr->usedTime;
                    cre[j].num -= ptr->num;
                    Running ( p, j, cre );
                }
                //执行下一个作业
                p = ready[j];
                if ( p != NULL )
                {
                    ready[j] = p->next;
                    p->next = NULL;
                }

            }
            else
            {
                JCB*q1;
                q1 = ready[j + 1];
                //找到第一个使用该资源的且未释放的进程q1
                while ( q1 != NULL && q1->IsUsed == 0 )
                    q1 = q1->next;
                if ( q1 == NULL )
                    return;
                times = q1->reachtime;
                resource* ptr1 = q1->res;
                while ( ptr1 != NULL && strcmp ( ptr1->name, cre[j].name ) )
                    ptr1 = ptr1->link;
                if ( ptr1 == NULL )
                    return;
                cre[j].num += ptr1->num;
                q1->IsUsed = 0;
            }

        }
        times=0;//重设时间
        JCB* pt = ready[j+1];
        while (pt != NULL)
        {
            pt ->IsUsed = 1;
            pt = pt ->next;
        }

    }
}
int main()
{
    int m;
    resource cre[3];//计算机资源
    //初始化计算机资源0为输入设备,1为cpu,2为输出设备
    //输入设备
    strcpy(cre[0].name, "INS");
    cre[0].num = 2;
    //CPU
    strcpy(cre[1].name, "CPU");
    cre[1].num = 4;
    //输出设备
    strcpy(cre[2].name, "OUTS");
    cre[2].num = 2;
    //初始化三个队列
    int id=0;
    for(id=0; id<4; id++)
        ready[id]=NULL;
    //输入m个作业
    printf("输入要输入的作业总数: ");
    scanf("%d", &m);
    getchar();
    init(m);
    FCFS(cre);
    q = ready[3];
    while(q != NULL)
    {
        ready[3] = q -> next;
        free(q);
        q=q->next;
    }
    return 0;
}

3、## 基于优先级调度的多道系统的作业调度模拟程序
#include <iostream>
#include <cstdio>
#include <cstdlib>

using namespace std;

struct JCB
{
    string ID;                                       //作业号
    int priority;                                            //优先级
    double begin_time;                               //提交时间
    double rtime;                                    //已经运行时间
    double turnaround_time;                          //周转时间
    double cpu_service_time;                         //占用CPU的时间
    double io_time;                                  //用于I/O的时间
    double finish_time;                              //完成时间
    double Wturnaround_time;                         //带权周转时间
    JCB& operator = (const JCB& p2)                 //重载 = 运算符,方便排序
    {
        this->priority = p2.priority;
        this->begin_time = p2.begin_time;
        this->rtime = p2.rtime;
        this->finish_time = p2.finish_time;
        this->cpu_service_time = p2.cpu_service_time;
        this->io_time = p2.io_time;
        this->ID = p2.ID;
        this->turnaround_time = p2.turnaround_time;
        this->Wturnaround_time = p2.Wturnaround_time;
        return *this;
    }
};

typedef struct
{
    JCB data[100];

}JCBk;

const double CPU = 10.0;
const double index = 0.5;
JCBk jcb,jcb_1;
int n,number;

void init()                                                        //初始化作业块
{
    cout<<"please input the number of the job:";
    cin>>n;
    number = n;
    for(int i = 0; i<n; i++)
    {
        cout<<"process ID:";
        cin>>jcb.data[i].ID;
        cout<<jcb.data[i].ID<<"'s begin time:";
        cin>>jcb.data[i].begin_time;
        cout<<jcb.data[i].ID<<"'s cpu_service time:";
        cin>>jcb.data[i].cpu_service_time;
        cout<<jcb.data[i].ID<<"'s I/O time:";
        cin>>jcb.data[i].io_time;
        cout<<jcb.data[i].ID<<"'s priority:";
        cin>>jcb.data[i].priority;
        jcb.data[i].rtime = 0;
    }
    for(int i = 0; i<n-1; i++)                                    //按照优先级从大到小排序
    {
        for(int j = i+1; j<n; j++)
        {
            if(jcb.data[i].priority < jcb.data[j].priority)
                swap(jcb.data[i],jcb.data[j]);
        }
    }
    for(int i = 0; i<n-1; i++)
    {
        for(int j = i+1; j<n; j++)
        {
            if(jcb.data[i].begin_time == jcb.data[j].begin_time && jcb.data[i].ID > jcb.data[j].ID)
                swap(jcb.data[i],jcb.data[j]);
        }
    }
}

void youxianji()                                                //优先级
{
    int j = 0;
    double running = CPU;
    double bt = jcb.data[0].begin_time;
    double gtt = 0;
    double gwtt = 0;
    double real_begin;
    double record = jcb.data[0].begin_time;
    int num = n-1;
    cout<<"ID     "<<"leave time  "<<"begin time  "<<"turnaround time  "<<"finish time  "<<"wighted turnaround time"<<endl;
    while(1)
    {
        if(jcb.data[j].cpu_service_time > CPU)
        {
            cout<<"over running range!!!"<<endl;
            exit(0);
        }
        jcb.data[j].rtime += index;
        record += index;
        if(running >= 0)
        {
            if (jcb.data[j].rtime >= jcb.data[j].cpu_service_time)
            {
                real_begin = bt;
                jcb.data[j].finish_time = record + jcb.data[j].io_time;
                jcb.data[j].turnaround_time = jcb.data[j].finish_time - jcb.data[j].begin_time;
                jcb.data[j].Wturnaround_time = jcb.data[j].turnaround_time / jcb.data[j].rtime;
                cout<<jcb.data[j].ID<<"         "<<real_begin<<"                "
                <<jcb.data[j].begin_time<<"                  "<<jcb.data[j].turnaround_time
                <<"              "<<jcb.data[j].finish_time<<"                 "
                <<jcb.data[j].Wturnaround_time<<endl;
                n--;
                running -= jcb.data[j].cpu_service_time;
                bt = record;
                gtt += jcb.data[j].turnaround_time;
                gwtt += jcb.data[j].Wturnaround_time;
            }
            else
            {
                num++;
                swap(jcb.data[num],jcb.data[j]);
            }
        }
        else
        {
            running += jcb.data[j].cpu_service_time;
            num++;
            swap(jcb.data[num],jcb.data[j]);
        }
        if(n == 0)
            break;
        j++;
    }
    cout<<" average of turnaround time:"<<gtt/number<<endl<<"average of wighted turnaround time:"<<gwtt/number<<endl;
}


int main()
{
    init();
    youxianji();
    return 0;
}