調度算法之最短作業優先算法


最短作業優先算法又叫做短進程優先算法

寫此博文目的:

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("進程名\t到達時間\t運行時間\n");
    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  \t%d             \t%d\n", pcbs[index].processName, pcbs[index].arriveTime, pcbs[index].runTime);
    }
    printf("\n***********************************************\n");
}
void printfPcbsInfo()//打印所有進程的所有信息
{
    printf("當前時間為:%d時各進程的信息.....\n\n",currentTime);
    printf("進程名\t到達時間\t運行時間\t開始時間\t結束時間\t周轉時間\t帶權周轉時間\t狀態\n");
    for(int index=0; index<PNUMBER; index++)
    {
        printf("%s\t%8d\t%8d\t%8d\t%8d\t%8d\t%8d\t%4s\n",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;
}

輸入文本如下:

運行結果如下:

 

如果有不足錯誤的地方,歡迎大家拍磚指正哦!!!

天氣不錯。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM