最短作业优先算法(不完善)

最短作业优先(SJF)

问题描述:

最短作业优先(SJF)是一种调试任务请求的调试策略。每个任务请求都含有请求时间(即向系统提交请求的时间)和持续时间(即完成任务所需时间)属性。当前任务完成后,SJF策略选择最短持续时间的任务执行;如果多个任务具有相同持续时间,那么选择请求时间最早的任务。任务的等待时间为实际开始的时间和请求时间的差值。

给定任务的请求时间和持续时间列表,设计一个程序,使用短作业优先算法求平均等待时间。

函数说明

实现方法:

float minWaitingTime(int *requestTimes,int *durations,int n)

输入:requestTimes 表示任务请求时间的整数列表;durations 表示任务持续时间的整数列表;n 表示任务的数量。

输出:返回使用**非抢占式**SJF调度而计算出的所有任务平均等待时间浮点数。

举例:

requestTimes={0,2,4,5},durations={7,4,1,4},n=4时,返回平均等待时间为4.000000。

下面为个人写的实现代码,有某些用例测试无法通过:


float minWaitingTime(int *requestTimes,int *durations,int n)
{   
    /*方法一:自己所写*/
    int ctime=0;        //当前时间
    int *wtime=(int*)malloc(n*sizeof(int));     //每个作业的等待时间
    int *flag=(int*)malloc(n*sizeof(int));      //每个作业是否执行的标志,若执行则置1
    int i=0;            //总循环变量
    int next=0;         //下一个进入处理的作业序号
    int min=500;        //最短的作业运行时间随,开始的时候便取个很大的值
    float totaltime=0;
    for(;i<n;i++)       //初始将每个作业等待时间和其标志都置0
    {
        wtime[i]=0;
        flag[i]=0;
    }
    for(i=0;i<n;i++)
    {
        if(i==0)        //第一次执行的时候,不用考虑作业的运行时间长短,直接把requestTimes[0]==0所对应的那个作业投入运行   &&requestTimes[0]==0
        {
            //if(requestTimes[0]!=0)    ctime+=requestTimes[0];
            flag[i]=1;
            ctime+=durations[i];
            for(int j=0;j<n;j++)                //只有当该作业还没被运行时,才能累加等待时间
            {
                if(flag[j]==0)
                {
                    wtime[j]=ctime-requestTimes[j];
                }
            }
        }
        else                                    //if(requestTimes[0]!=0)
        {
            for(int k=0;k<n;k++)                //找出剩下的作业中,运行时间最短的一个
            {
                if(flag[k]==0)                  //如果其标志为0,则是剩下的没有运行的作业
                {
                    if(durations[k]<min)        //找出运行时间最小的那个
                    {
                        min=durations[k];       
                        next=k;
                    }
                }
            }
            flag[next]=1;                       //将最小运行时间那个作业置1,表示它被运行了
            ctime=ctime+min;                    //此时系统时间加上最小的运行时间
            min=500;                            //又要将min取到非常非常大以进入下一次循环
            for(int m=0;m<n;m++)
            {
                if(flag[m]==0)                  //当该作业还没被运行时,才能累加等待时间
                {
                    wtime[m]=ctime-requestTimes[m];     //用当前的系统时间减去它的开始时间,即得到其等待时间
                }
            }
        }
    }
    for(i=0;i<n;i++)                //计算总等待时间
    {
        totaltime+=wtime[i];
    }

    return totaltime/n;             //返回平均等待时间

/*方法二:参考http://blog.csdn.net/u013749540/article/details/52312910内容
    int *flag=(int*)malloc(n*sizeof(int));      //每个作业是否执行的标志,若执行则置1
    int *ready=(int*)malloc(n*sizeof(int));     //还未运行,并且在当前时间前就已经就绪的作业(即处于等待状态)    
    int ready_n=0;                              //还未运行并且已经处于等待状态的作业数
    int ctime=0;        //当前时间
    float wtime=0;      //已运行作业的总等待时间
    int current=0;      //当前作业的序号
    int next=0;         //下一个进入处理的作业序号
    int min=500;        //最短的作业运行时间,开始的时候便取个很大的值
    int i=0;            //总循环变量
    for(;i<n;i++)       //初始将每个作业等待时间和其标志都置0
    {
        ready[i]=0;
        flag[i]=0;
    }

    for(i=0;i<n;i++)
    {
        //if(i==0&&requestTimes[0]!=0)  ctime=requestTimes[0];

        wtime=wtime+(ctime-requestTimes[current]);      //已运行的总等待时间=上一次wtime+当前系统时间-作业开始时间
        ctime=ctime+durations[current];                 //目前的系统时间=上一次ctime+当前作业运行时间
        flag[current]=1;                                //编号为current的作业运行了就将其标志置1

        ready_n=0;
        for(int j=0;j<n;j++)                            //将还未运行并且已经处于等待状态的作业编号装入ready[]数组
        {
            if(flag[j]==0&&requestTimes[j]<=ctime)
            {
                ready[ready_n++]=j;
            }
        }

        min=500;
        for(int k=0;k<ready_n;k++)                      //从ready[]数组中把运行时间最少的那个作业找出来,并将其编号赋给next
        {
            if(durations[ready[k]]<min)
            {
                min=durations[ready[k]];
                next=ready[k];
            }
        }       
        current=next;                                   //将下一个任务赋给当前任务,进入下一次循环
    }
    return wtime/n;             //返回平均等待时间  
*/
}

void main()
{
    int retime[]={0,2,4,5};//{1,1,1,2};//
    int drtime[]={7,4,1,4};//{4,3,5,1};//
    int n=sizeof(retime)/sizeof(int);
    float wt=minWaitingTime(retime,drtime,n);
    printf("平均等待时间为:%f\n",wt);
}

NOTE:上述两种方法均没考虑到requestTimes[0]!=的情况,用例requestTimes={1,1,1,2},durations={4,3,5,1},n=4无法通过。

1. 实验目的 调度的实质是操作系统按照某种预定的策略来分配资源。进程调度的目的是分配CPU资源。由于进程调度程序执行的频率很高,因此调度算法的好坏直接影响到操作系统的性能。本实验的目的是编程模拟实现几种常用的进程调度算法,通过对几组进程分别使用不同的调度算法,计算进程的平均周转时间和平均带权周转时间,比较各种算法的性能优劣。 2. 实验原理 [1]. 进程调度算法描述 进程调度算法包括先来先服务调度算法最短作业时间优先(抢占式和非抢占式)、最高响应比调度算法4种。(每个人必须做FCFS,然后在后面的三种中任选一种,即每个人必须做2种调度算法的模拟。) [2]. 衡量算法性能的参数 计算进程的平均周转时间和平均带权周转时间。 3. 实验内容 (1)编程实现本实验的程序,要求: [1]. 建立进程的进程控制块,进程控制块至少包括: a) 进程名称; b) 进程需要执行时间; c) 进入就绪队列时间; d) 进程执行开始时间 e) 进程执行结束时间 [2]. 编程实现调度算法。 [3]. 进程及相关信息的输入。这些信息可以直接从键盘上输入,也可以从文件读取。 [4]. 时间片与时间流逝的模拟。本实验需要对算法的执行计时,程序应该提供计算时间的方。一种最简单的方是使用键盘,比如每敲一次空格代表一个时间片的流逝。另一种方是使用系统时钟。 [5]. 一组进程序列执行完毕,打印出结果信息。程序需要计算出每个进程的开始执行时间、结束时间、周转时间和带权周转时间,并为整个进程序列计算平均周转时间和平均带权周转时间。程序将计算结果按一定的格式显示在计算机屏幕上或输出到文件中。打印出进程调度顺序图。 [6]. 实现数据在磁盘文件上的存取功能。 (2)对下列就绪进程序列分别使用上面的几种算法进行调度,计算每种算法下的平均周转时间和平均带权周转时间。 进程号 到达时间 要求执行时间 0 0 1 1 1 35 2 2 10 3 3 5 4 6 9 5 7 21 6 9 35 7 11 23 8 12 42 9 13 1 10 14 7 11 20 5 12 23 3 13 24 22 14 25 31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值