【操作系统&C语言】作业调度算法 先来先服务&短作业优先

FCFS(先来先服务)算法

算法思想
系统将按照作业到达的先后次序来进行调度

示例

作业编号 提交时间 执行时间
1 8.0 2.0
2 8.5 0.5
3 9.0 0.1
4 9.5 0.2
5 9.8 0.8

采用先来先服务算法,那么作业的调度顺序就是
1->2->3->4->5
可以得到下面这张表

进程编号 提交时间 执行时间 开始时刻 完成时刻 周转时间 周转系数
1 8.0 2.0 8.0 10.0 2.0 1
2 8.5 0.5 10.0 10.5 2 4
3 9.0 0.1 10.5 10.6 1.6 16
4 9.5 0.2 10.6 10.8 1.3 6.5
5 9.8 0.8 10.8 11.6 1.8 2.25

简单代码实现

定义一个作业的结构体

typedef struct  _Job
{
    int num;
    double Subtime;
    double Exetime;
    double Starttime,Finishtime;
    double T,W;//T 周转时间,W周转系数
}Job;

定义一个存放作业的结构体

#define MAXJOBNUM 10
typedef struct _JobArr
{
    Job arr[MAXJOBNUM];
    int len;
}JobArr;

从文件中读取要处理的作业

void readFile(const char*filename,JobArr*jobarr)
{
	FILE*file;
    file=fopen(filename,"r");
    char buf[BUFSIZ]={0};
    fgets(buf, BUFSIZ, file);//读取表头文字
    int i=0;
    while (fgets(buf,BUFSIZ,file))
    {
        Job job={0};
        sscanf(buf,"%d %lf %lf",&job.num,&job.Subtime,&job.Exetime);
        printf("%d %lf %lf\n",job.num,job.Subtime,job.Exetime);
        jobarr->arr[jobarr->len++]=job;
        if(i>=10)
        {
            printf("作业太多了\n");
            fclose(file);
            return;
        }
    }
    fclose(file);
}

计算完成时间、周转时间等

//在main函数中
	JobArr jobarr;
    jobarr.len=0;
    readFile("./Jobin.txt",&jobarr);
    jobarr.arr[0].Starttime=jobarr.arr[0].Subtime;
    jobarr.arr[0].Finishtime=jobarr.arr[0].Starttime+jobarr.arr[0].Exetime;
    jobarr.arr[0].T=jobarr.arr[0].Finishtime-jobarr.arr[0].Subtime;
    jobarr.arr[0].W=jobarr.arr[0].T/jobarr.arr[0].Exetime;
    for(int i=1;i<jobarr.len;i++)
    {
        jobarr.arr[i].Starttime=jobarr.arr[i-1].Finishtime;
        jobarr.arr[i].Finishtime=jobarr.arr[i].Starttime+jobarr.arr[i].Exetime;
        jobarr.arr[i].T=jobarr.arr[i].Finishtime-jobarr.arr[].Subtime;
        jobarr.arr[i].W=jobarr.arr[].T/jobarr.arr[i].Exetime;
    }

打印信息

void print(JobArr jobarr)
{
	double avrT,avrW;
    printf("%5s %5s %5s %5s %5s %5s %5s\n","作业编号","提交时间","执行时间","开始时间","完成时间","周转时间","周转系数");
    for(int i=0;i<jobarr.len;i++)
    {
        printf("%-8d %-8.2lf %-8.2lf %-8.2lf %-8.2lf %-8.2lf %-8.2lf\n",jobarr.arr[i].num,jobarr.arr[i].Subtime,jobarr.arr[i].Exetime,jobarr.arr[i].Starttime,jobarr.arr[i].Finishtime,jobarr.arr[i].T,jobarr.arr[i].W);
        avrT+=jobarr.arr[i].T/jobarr.len;
        avrW+=jobarr.arr[i].W/jobarr.len;
        
    }
    printf("平均周转时间%lf\t\t平均周转系数%lf",avrT,avrW);
}

【操作系统&C语言】作业调度算法 先来先服务&短作业优先_第1张图片

SJF(短作业优先)算法

算法思想
系统从作业队列中选择执行时间最短的作业执行,作业的时间越短,优先级越高

作业序号 提交时间 执行时间
1 8 2
2 8.5 0.5
3 9 0.1
4 9.5 0.3
5 10.1 0.2

采用短作业优先算法,作业的调度顺序
1->3->4->2->5
可能有人会认为作业的调度顺序是3->5->4->2->1或者是1->3->5->4->2,那么为什么不是这样

最早提交的那个作业是第一个处理的(和执行时间的长短无关) 作业1处理完的时间是10.0那么在这个时候作业2、作业3、作业4已经提交了,这个时候处理那一个就根据作业执行时间的长短来确定,作业5的提交时间是10.1那么就要等到作业2、作业3、作业4处理完之后处理了。

进程编号 提交时间 执行时间 开始时刻 完成时刻 周转时间 周转系数
1 8.0 2.0 8.0 10.0 2.0 1
3 9.0 0.1 10.0 10.1 1.1 11
4 9.5 0.2 10.1 10.3 0.8 4
2 8.5 0.5 10.3 10.8 2.3 4.6
5 10.1 0.2 10.8 11.0 0.9 4.5

代码实现

定义一个作业的结构体

typedef struct  _Job
{
    int num;
    double Subtime;
    double Exetime;
    double Starttime,Finishtime;
    double T,W;//T 周转时间,W周转系数
}Job;

定义一个存放作业的结构体

#define MAXJOBNUM 10
typedef struct _JobArr
{
    Job arr[MAXJOBNUM];
    int len;
}JobArr;

定义一个存放作业处理顺序的结构体(输出用)

typedef struct _OutPutArr
{
    Job arr[MAXJOBNUM];
    int len;
}OutPutArr;

从文件中读取要处理的作业

void readFile(const char*filename,JobArr*jobarr)
{
    FILE*file;
    file=fopen(filename,"r");
    char buf[BUFSIZ]={0};
    
    fgets(buf, BUFSIZ, file);//读取表头文字
    int i=0;
    while (fgets(buf,BUFSIZ,file))
    {
        Job job={0};
        sscanf(buf,"%d %lf %lf",&job.num,&job.Subtime,&job.Exetime);
        jobarr->arr[jobarr->len++]=job;
        if(i>=10)
        {
            printf("作业太多了\n");
            fclose(file);
            return;
        }
    }
    fclose(file);
    
}

处理提交的第一个作业

//在main函数中
	JobArr jobarr={0};
    ReadyArr readyarr={0};
    OutPutArr outputarr={0};//输出用
    
    readFile("./JobIn.txt",&jobarr);
    //处理最先提交的那一个作业
    jobarr.arr[0].Starttime=jobarr.arr[0].Subtime;
    jobarr.arr[0].Finishtime=jobarr.arr[0].Starttime+jobarr.arr[0].Exetime;
     jobarr.arr[0].T=jobarr.arr[0].Finishtime-jobarr.arr[0].Subtime;
    jobarr.arr[0].W=jobarr.arr[0].T/jobarr.arr[0].Exetime;
    
    double curTime=jobarr.arr[0].Finishtime;//用来判断从这个作业提交到处理完有那些作业提交了
    outputarr.arr[outputarr.len++]=jobarr.arr[0];

处理剩余的作业

	for(int i=1;i<jobarr.len;)
    {
        //找出就绪作业 subtime
        int j=0;//就绪作业的个数
        for(int k=i;k<jobarr.len;k++)
        {
            if(jobarr.arr[k].Subtime<=curTime)
            {  
                //找到就插入到就绪数组中
                Insert(&readyarr,jobarr.arr[k]);
                j++;
            }
        }
        //处理作业,计算时间
        for(int z=0;z<readyarr.len;z++)
        {
           	if(z==0)
            {
                readyarr.arr[z].Starttime=curTime;
            }
            else
            {
                readyarr.arr[z].Starttime=readyarr.arr[z-1].Finishtime;
            }
            readyarr.arr[z].Finishtime=readyarr.arr[z].Starttime+readyarr.arr[z].Exetime;
            readyarr.arr[z].T=jobarr.arr[z].Finishtime-jobarr.arr[z].Subtime;
            readyarr.arr[z].W=jobarr.arr[z].T/jobarr.arr[z].Exetime;
            //插入输出数组
            outputarr.arr[outputarr.len++]=readyarr.arr[z];
           //更新当前时间
           	curTime= readyarr.arr[z].Finishtime;
        }
        //就绪作业处理完了,清空就绪数组
        Clear(&readyarr);
        i+=j;
        
    }
    print(&outputarr);

插入就绪数组

【操作系统&C语言】作业调度算法 先来先服务&短作业优先_第2张图片

void Insert(ReadyArr*readyarr,Job job)
{
    if(readyarr->len==0)
    {
        readyarr->arr[readyarr->len++]=job;
        return;
    }
    else
    {
        for(int i=0;i<readyarr->len;i++)
        {
        
       
            if(job.Exetime>readyarr->arr[i].Exetime)
            {
                continue;//job一定是在这个比较元素后面,和下一个元素比较
            }


            else if(job.Exetime==readyarr->arr[i].Exetime)//如果执行时间相同,就比较提交时间
            {
                if(job.Subtime<=readyarr->arr[i].Subtime)//如果job提交时间要早,就插入到这个比较位,其余元素后移
                {
                    for(int j=readyarr->len+1;j>i;j--)
                    {
                        readyarr->arr[j]=readyarr->arr[j-1];
                    }
                    readyarr->arr[i]=job;
                    readyarr->len++;
                    return;
                }
                else
                {
                    continue;//job一定是在这个比较元素后面,和下一个元素比较
                }
            }
            else
            {
                for(int j=readyarr->len+1;j>i;j--)
                {
                    readyarr->arr[j]=readyarr->arr[j-1];
                }
                readyarr->arr[i]=job;
                readyarr->len++;
                return;
            }   
            
        }
        readyarr->arr[readyarr->len++]=job;//job执行时间比所有元素都大,插入到最后
    }
}

清空就绪数组

void Clear(ReadyArr*readyarr)
{
    for(int i=0;i<readyarr->len;i++)
        memset(readyarr->arr,0,sizeof(readyarr->arr));
    readyarr->len=0;
}

打印结果

void print(OutPutArr*outputarr)
{
    printf("%5s %5s %5s %5s %5s %5s %5s\n","作业编号","提交时间","执行时间","开始时间","完成时间","周转时间","周转系数");
    double avrT,avrW;
    for(int i=0;i<outputarr->len;i++)
    {
        printf("%-8d %-8.2lf %-8.2lf %-8.2lf %-8.2lf %-8.2lf %-8.2lf\n",outputarr->arr[i].num
        ,outputarr->arr[i].Subtime,outputarr->arr[i].Exetime,outputarr->arr[i].Starttime,outputarr->arr[i].Finishtime,
        outputarr->arr[i].T,outputarr->arr[i].W);
        avrT+=outputarr->arr[i].T/10;
        avrW+=outputarr->arr[i].W/10;
    }
     printf("平均周转时间%lf\t\t平均周转系数%lf",avrT,avrW);
}

【操作系统&C语言】作业调度算法 先来先服务&短作业优先_第3张图片
【操作系统&C语言】作业调度算法 先来先服务&短作业优先_第4张图片

点击这里获取代码

你可能感兴趣的:(算法,c语言)