• 调度算法之最短作业优先算法


    最短作业优先算法又叫做短进程优先算法

    写此博文目的:

    1.方便自己复习

    2.给正在学习此算法的人一点参考

    单道(一次只能运行一个进程)

    分析:

    先将进程按照到达时间升序排序,第一个进程到达的时候不等待,直接运行,因为他是第一个到达的进程,在他之前没有进程在运行,当有进程到达但是有其他进程在运行的时候,到达的进程处于等待状态,当某个正在运行的进程运行完毕的时候,需要选择下一个进程,依据是:处于等待状态的进程,且运行时间最短(当有多个进程处于等待状态的时候,选择运行时间最短的进程,这个结束最短作业优先算法的核心)

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    #define TAKEIN "takein"//对应的进程状态
    #define WAIT "wait"
    #define RUN "run"
    #define FINISH "finish"
    #define PNUMBER 5//进程个数
    
    typedef struct pcb
    {
        char processName[20];//进程名称
        int arriveTime;//进程到达时间
        int startTime;//进程开始时间
        int endTime;//进程结束时间
        int runTime;//进程运行时间大小
        int turnOverTime;//周转时间
        int userweightTurnOverTime;//带权周转时间
        char provessStatus[10];//进程状态
    } pcb;
    
    pcb pcbs[PNUMBER];//进程数组
    
    int currentTime=0;//时间
    
    int processIndex=0;//进程的编号
    
    void createPcbs()//进程初始化函数
    {
        freopen("input.txt","r",stdin);//以只读操作读文件
        printf("进程名	到达时间	运行时间
    ");
        for(int index=0; index<PNUMBER; index++)//遍历所有进程,给进程赋初值
        {
            scanf("%s",pcbs[index].processName);
            scanf("%d",&pcbs[index].arriveTime);
            scanf("%d",&pcbs[index].runTime);
            pcbs[index].endTime=0;
            pcbs[index].startTime=0;
            pcbs[index].turnOverTime=0;
            pcbs[index].userweightTurnOverTime=0;
            strcpy( pcbs[index].provessStatus,TAKEIN);
            printf("%s  	%d             	%d
    ", pcbs[index].processName, pcbs[index].arriveTime, pcbs[index].runTime);
        }
        printf("
    ***********************************************
    ");
    }
    void printfPcbsInfo()//打印所有进程的所有信息
    {
        printf("当前时间为:%d时各进程的信息.....
    
    ",currentTime);
        printf("进程名	到达时间	运行时间	开始时间	结束时间	周转时间	带权周转时间	状态
    ");
        for(int index=0; index<PNUMBER; index++)
        {
            printf("%s	%8d	%8d	%8d	%8d	%8d	%8d	%4s
    ",pcbs[index].processName,pcbs[index].arriveTime,pcbs[index].runTime,pcbs[index].startTime,pcbs[index].endTime,pcbs[index].turnOverTime,pcbs[index].userweightTurnOverTime,pcbs[index].provessStatus);
        }
    }
    void sortPcbs()//按到达时间的升序排序
    {
        int minIndex=0,minValue=0;
        for(int i=0; i<PNUMBER; i++)
        {
            minIndex=i;
            minValue=pcbs[i].arriveTime;
            for(int j=i; j<PNUMBER; j++)
            {
                if(pcbs[j].arriveTime<minValue)
                {
                    minValue=pcbs[j].arriveTime;//保存最小的
                    minIndex=j;
                }
            }
            pcb temp=pcbs[minIndex];//交换
            pcbs[minIndex]=pcbs[i];
            pcbs[i]=temp;
        }
    }
    int selNectProcess()//下一个进程的选择,条件:等待状态&&运行时间最短
    {
        int result=-1;
        int minTime=100;
        for(int index=0; index<PNUMBER; index++)
        {
            if(strcmp(pcbs[index].provessStatus,WAIT)==0)//进程处于等待状态
            {
                if(pcbs[index].runTime<minTime)//且运行时间最短
                {
                    minTime=pcbs[index].runTime;
                    result=index;
                }
            }
        }
        return result;//返回下一个运行的进程的编号
    }
    int isHasProcessArrive()//检查在某一个时间点有没有进程到达
    {
        int result=-1;
        for(int index=0; index<PNUMBER; index++)
        {
            if(pcbs[index].arriveTime==currentTime)//某个进程的到达时间等于当前时间
            {
                result=index;
                strcpy(pcbs[index].provessStatus,WAIT);//改变进程状态
            }
        }
        return result;
    }
    
    void runProcess(int pindex)
    {
        int runTime=pcbs[pindex].runTime;
        //进程开始,需要改变进程的相关信息
        pcbs[pindex].startTime=currentTime;
        pcbs[pindex].endTime=pcbs[pindex].startTime+pcbs[pindex].runTime;
        strcpy(pcbs[pindex].provessStatus,RUN);
        printfPcbsInfo();//输出此时进程的信息
        for(int k=1; k<=runTime; k++) //进程运行中
        {
            currentTime++;//时间转动
            isHasProcessArrive();
            if(k==runTime)//进程结束条件
            {
                //改变进程相关信息
                strcpy(pcbs[pindex].provessStatus,FINISH);
                pcbs[pindex].turnOverTime=pcbs[pindex].endTime-pcbs[pindex].arriveTime;
                pcbs[pindex].userweightTurnOverTime=pcbs[pindex].turnOverTime*1.0/pcbs[pindex].runTime;
            }
            printfPcbsInfo();//打印进程此时信息
        }
        processIndex++;//准备运行下一个进程
        currentTime--;//收回一个时刻,因为下一个进程在此时运行
    }
    void startProcess()//开始进程的调度
    {
        int firstArriveTime=pcbs[0].arriveTime;//第一个到达的进程
        int nextIndex=0;
        printfPcbsInfo();
        while(1)
        {
            currentTime++;//时间流动
            isHasProcessArrive();//检查这个时候有没有新到达的进程
            if(currentTime<firstArriveTime)//第一个进程都没有到
            {
                printfPcbsInfo();
            }
            else if(currentTime==firstArriveTime)
            {
                runProcess(0);//执行进程
            }
            else //第一个进程执行完毕,选择下一个进程
            {
                nextIndex=selNectProcess();
                if(nextIndex!=-1)//存在下一个将要执行的进程
                {
                    runProcess(nextIndex);
                }
                if(processIndex==PNUMBER)//所有进程执行完毕
                    break;//跳出循环
            }
        }
    }
    int main()
    {
        createPcbs();//进程相关信息的初始化
        sortPcbs();//进程按照到达时间升序排序
        startProcess();//开始进程的调度
        return 0;
    }

    输入文本如下:

    运行结果如下:

    如果有不足错误的地方,欢迎大家拍砖指正哦!!!

    天气不错。。。

  • 相关阅读:
    Android APK瘦身方法小结
    快速了解Android重要机制
    Android 画笔Paint
    android 图片凸出
    金钱转换
    WPF属性与特性的映射(TypeConverter)
    XMAL 中x名称控件的Auttribute
    AtCoder Grand Contest 012 B
    scau 17967 大师姐唱K的固有结界
    Centos7开机自动启动服务和联网
  • 原文地址:https://www.cnblogs.com/yinbiao/p/8761181.html
Copyright © 2020-2023  润新知