最短作業優先算法又叫做短進程優先算法
寫此博文目的:
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; }
輸入文本如下:
運行結果如下:
如果有不足錯誤的地方,歡迎大家拍磚指正哦!!!
天氣不錯。。。