调度算法之最短作业优先算法
最短作业优先算法又叫做短进程优先算法
写此博文目的:
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; }
输入文本如下:
运行结果如下:
如果有不足错误的地方,欢迎大家拍砖指正哦!!!
天气不错。。。
心之所向,素履以往
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南