一、目的和要求

1. 实验目的

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

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

2.实验要求

用高级语言编写一个或多个作业调度的模拟程序。

单道批处理系统的作业调度程序。作业一投入运行,它就占有计算机的一切资源直到作业完成为止,因此调度作业时不必考虑它所需要的资源是否得到满足,它所运行的时间等因素。

     作业调度算法:

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

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

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

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

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

二、实验内容

根据指定的实验课题,完成设计、编码和调试工作,完成实验报告。

、源代码

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct job
{
    char name[10]; //作业名
    char status;    

    int arrtime;    //到达时间
    int reqtime;    //要求服务时间
    int startime;    //开始时间
    int finitime;    //结束时间

    float TAtime,TAWtime;    //周转时间、带权周转时间
    float prio;        //优先级
    float resratio;//响应比

}jobarr[24],jobfin[24],job[24];
int systime=0,num=0;
int intarr,intfin,intjob;
int temp[100];


void accordingTheInformation();//显示信息
void sort();//按到达时间进行排序
void output();//输出结果

void dataAccess();//选择数据的获取方式

void readFile();//读取文件
void manuallyEnter();//手动输入模拟函数

void algorithmMenu();//算法菜单

void FCFS();//FCFS算法
void SJF();//SJF算法
void HRRF();//HRRF算法


main()
{
    //调用选择数据的获取方式方法
    dataAccess();

}


//显示信息
void accordingTheInformation()
{

    printf("\n\n\t作业名  到达时间  CPU所需时间\n");
    for(int i=0;i<num;i++){
        printf("\t  %s\t   %d\t\t%d\n",job[i].name,job[i].arrtime,job[i].reqtime);
    }
}

//按到达时间进行排序
void sort()
{
    
    int i,j,k = 0;
    for(i=0;i<num;i++)
        temp[i]=i;

    //按作业到达时间进行排序
    for(i=0;i<num;i++){
        for(j=i+1;j<num;j++){
            if(job[temp[i]].arrtime>job[j].arrtime){
                k = temp[i];
                temp[i] = temp[j];
                temp[j] = k;
            }
        }
    }

}

//输出结果
void output()
{
    int i;
    float AVGTAtime=0,AVGTAWtime=0;  //平均周转时间,平均带权周转时间

    //计算周转时间、带权周转时间
    job[temp[0]].startime = job[temp[0]].arrtime;
    job[temp[0]].finitime = job[temp[0]].startime + job[temp[0]].reqtime;
    job[temp[0]].TAtime = (float)job[temp[0]].finitime - job[temp[0]].arrtime;
    job[temp[0]].TAWtime = job[temp[0]].TAtime/job[temp[0]].reqtime;
    for(i=1;i<num;i++){
        job[temp[i]].startime = job[temp[i-1]].finitime;
        job[temp[i]].finitime = job[temp[i]].startime + job[temp[i]].reqtime;
        job[temp[i]].TAtime = (float)job[temp[i]].finitime - job[temp[i]].arrtime;
        job[temp[i]].TAWtime = job[temp[i]].TAtime/job[temp[i]].reqtime;
    }

    //输出相关内容
    printf("\n\n经按到达时间排序后,未达到队列是\n");
    printf("作业名  到达时间  CPU所需时间  开始时间  结束时间  周转时间  带权周转时间\n");
    for(i=0;i<num;i++)    
    {
        printf("  %s\t   %d\t\t%d\t  %d\t    %d\t   %f\t%f\n",job[temp[i]].name,job[temp[i]].arrtime,
            job[temp[i]].reqtime,job[temp[i]].startime,job[temp[i]].finitime,job[temp[i]].TAtime,job[temp[i]].TAWtime);
    }
    
    //计算平均周转时间、平均带权周转时间
    for(i=0;i<num;i++)
    {
        AVGTAtime += job[temp[i]].TAtime;
        AVGTAWtime += job[temp[i]].TAWtime;
    }
    printf("\n\n平均周转时间=%f\n",AVGTAtime/num);
    printf("平均带权周转时间=%f\n\n",AVGTAWtime/num);
}


//FCFS算法
void FCFS()
{
    printf("\n\n* * * * * * * 先来先服务算法FCFS * * * * * * *");
    //显示信息
    accordingTheInformation();

    //按到达时间进行排序
    sort();

    //输出结果
    output();

    //再次调用算法菜单
    algorithmMenu();
}


//SJF算法
void SJF()
{
    int i,j,k = 0;

    printf("\n\n* * * * * * * 最短作业优先算法SJF * * * * * * *");
    //显示信息
    accordingTheInformation();

    //按到达时间进行排序
    sort();
    
    //按需要服务时间进行排序
    for(i=0;i<num;i++){
        for(j=i+1;j<num;j++){
            if(job[temp[i]].reqtime>job[j].reqtime && temp[i]!=0){
                k = temp[i];
                temp[i] = temp[j];
                temp[j] = k;
            }
        }
    }
    
    //输出结果
    output();

    //再次调用算法菜单
    algorithmMenu();


}

//HRRF算法
void HRRF(){
    int i,j,k=0;
    printf("\n\n* * * * * * * 响应比最高者优先算法HRRF * * * * * * *");
    //显示信息
    accordingTheInformation();
    //按到达时间进行排序
    sort();

    //计算最高响应比
    for(i=0;i<num;i++){
        if(temp[i]!=0){
            job[temp[i]].resratio = 1 + (float)(job[0].reqtime+job[0].arrtime-job[temp[i]].arrtime)/job[temp[i]].reqtime;
        }
    }
/*
    for(i=0;i<num;i++){
        printf("%f\n",job[temp[i]].resratio);
    }
*/

    //按最高响应比进行排序
    for(i=0;i<num;i++){
        for(j=i+1;j<num;j++){
            if(job[temp[i]].resratio<job[j].resratio && temp[i]!=0){
                k = temp[i];
                temp[i] = temp[j];
                temp[j] = k;
            }
        }
    }
    

    //输出结果
    output();

    //再次调用算法菜单
    algorithmMenu();

    
}

//算法菜单
void algorithmMenu()
{
    int k;
    printf("\n\n\t**************************************\n");
    printf("\t\t1.FCFS算法调度\n");
    printf("\t\t2.SJF算法调度\n");
    printf("\t\t3.HRRF算法调度\n");
    printf("\t\t0.退出算法调度\n");
    printf("\t**************************************\n\n\n");
    printf("\t请选择菜单项: ");
    scanf("%d",&k);
    switch(k){
    case 1:
        //调用FCFS算法
        FCFS();
        break;
    case 2:
        //调用SJF算法
        SJF();
        break;
    case 3:
        //调用HRRF算法
        HRRF();
        break;
    case 0:
        //退出程序
        printf("\n\n\t已退出算法调度\n\n");
        break;
    default:
        printf("\n\n\t**请输出0-3的数字进行选择");
        algorithmMenu();
        break;
    }
}


//手动输入模拟函数
void manuallyEnter(){

    int i;
    printf("\n\t作业个数:");
    scanf("%d",&num);
    printf("\n");
    //循环输入信息
    for(i = 0;i<num;i++){
        printf("\t第%d个作业:\n",i+1);
        printf("\t输入作业名:");
        scanf("%s",&job[i].name);
        printf("\t到达时间:");
        scanf("%d",&job[i].arrtime);
        printf("\t要求服务时间:");
        scanf("%d",&job[i].reqtime);
        printf("\n");
    }
    //调用算法菜单
    algorithmMenu();
}


//读取文件
void readFile()
{
    //读取文件
    FILE *fp = fopen("job.txt","r");
    if(fp == NULL)
    {
        printf("File open error!\n");
        exit(0);
    }
    while(!feof(fp)&&fgetc(fp)!=EOF)
    {
        fseek(fp,-1L,SEEK_CUR);
        fscanf(fp,"%s%d%d",&job[num].name,&job[num].arrtime,&job[num].reqtime);
        num++;
    }
    fclose(fp);
    //显示读取到的文本信息
    accordingTheInformation();
    //调用算法菜单函数
    algorithmMenu();
}


//选择数据的获取方式
void dataAccess()
{
    int k;
    printf("\n\n\t**************************************\n");
    printf("\t\t1.调用文本写入数据\n");
    printf("\t\t2.调用自己输入模拟数据\n");
    printf("\t**************************************\n\n\n");
    printf("\t请选择菜单项: ");
    scanf("%d",&k);
    switch(k){
    case 1:
        readFile();
        break;
    case 2:
        manuallyEnter();
        break;
    default:
        printf("\n\n\t**请输出1或者2进行选择");
        dataAccess();
        break;
    }
}

四、实验结果

1.调用文本写入数据

 

 

 

2.调用FCFS算法

 

 

 

3.调用SJF算法

 

4.调用HRRF算法