操作系统课程设计:(JAVA)进程管理系统(附源码zip,jdk11,IDEA Ultimate2024 )
一.题目要求描述
本设计的目的是加深对进程概念及进程管理各部分内容的理解;熟悉进程管理中主要数据结构的设计及进程调度算法、进程控制机构、同步机构及通讯机构的实施。要求设计一个允许n个进程并发运行的进程管理模拟系统。
该系统包括有简单的进程控制、同步与通讯机构,其进程调度算法可任意选择。每个进程用一个PCB表示,其内容根据具体情况设置。各进程之间有一定的同步关系(可选)。系统在运行过程中应能显示或打印各进程的状态及有关参数的变化情况,以便观察诸进程的运行过程及系统的管理过程。
二、程序流程图及源代码注释
2.2 程序流程图
-
1.系统流程图

2.先来先服务(FCFS)算法:

3.短进程优先算法:

4.静态优先级调度算法:

5.时间片轮转调度算法:

2.2 核心函数源代码注释
1.先来先服务(FCFS)算法
void run()
{//*************************进入先来先服务算法(FCFS)*************************////模拟一个系统时间,系统时间自动增加,当某进程的到达时间 等于 该时刻系统时间时,该进程进入等待队列int systemTime = 0;int i = 0;//正在运行的进程的下标,i的范围:i <= j//按照到达系统时间排序后,最后一个到达系统的进程的下标j,int j = -1;//下标从0到j的进程都在等待队列中,j的范围:0 <= j <= num-1,初始队列中无进程,则为-1int flag = 0; //用于判断系统现在是否被进程占用,flag=1时表示系统正在运行进程totalTurnaroundTime = 0;//初始化周转总时间totalTurnaroundTimeWithRight = 0;//初始化带权周转总时间quickSortArriveTime(arr, 0, num-1);//进入算法后先按照进程到达时间进行升序排序//*************************系统开始运行,开始执行进程*************************//System.out.println("先来先服务算法(FCFS)开始运行");while(true){//模拟进程执行,从系统时间为0开始 到 最后一个进程执行结束System.out.println("当前时间:" + systemTime);//判断是否有进程进入系统(进入系统后进入等待队列),当有进程到达系统时,记录该进程并输出提示信息while(j+1 < num && systemTime == arr[j+1].getArriveTime()){//当该系统时间有到达的进程时,输出并记录进程到达系统,该判断独立执行,与flag无关//可能有多个进程同时到达,所以用while多次判断j++;System.out.println("进程" + arr[j].getName() + "到达系统");}//根据系统中是否有进程在执行,进行不同操作if(flag == 1){//flag=1表示 当前有进程在执行,判断该进程是否还在执行if(arr[i].getAlreadyServiceTime() != arr[i].getServiceTime()){//如果进程i已经服务的时间 != 应该服务的时间,即进程正在执行,则输出"正在执行"System.out.println("进程" + arr[i].getName() + "正在执行");//已经服务的时间和系统时间同步,应该在该时刻过去时增加,系统时间在程序末尾更新arr[i].setAlreadyServiceTime(arr[i].getAlreadyServiceTime() + 1);//更新已经服务的时间}else{//如果进程i已经服务的时间 = 应该服务的时间,即进程服务结束System.out.println("进程" + arr[i].getName() + "执行结束");arr[i].setEndTime(systemTime);//记录进程i结束服务时间//计算进程的周转时间、带权周转时间arr[i].setTurnaroundTime(arr[i].getEndTime() - arr[i].getArriveTime());arr[i].setTurnaroundTimeWithRight(arr[i].getTurnaroundTime() / (double)arr[i].getServiceTime());//记录周转总时间、带权周转总时间totalTurnaroundTime += arr[i].getTurnaroundTime();totalTurnaroundTimeWithRight += arr[i].getTurnaroundTimeWithRight();//if(i+1 <= j) i++;//执行完一个进程后,如果等待队列中还有进程,则i加1,准备执行下一个进程flag = 0;//进程执行完,flag置0,表明系统中无进程执行}}if(flag == 0)//此处不用else,因为上面flag=1时可能将flag置0,此flag=0和flag=1是可能都发生的{//flag=0表示 当前无进程在执行,如果等待队列中有进程,则执行一个进程if(i+1 <= j) i++;//执行完一个进程后,如果等待队列中还有进程,则i加1,准备执行下一个进程if(arr[i].getVisited() == 0){ //当等待队列中还有进程 并且 当前没有进程未被执行过//由于到达时间在最上面j的部分筛选过了,所以此处只需要筛选是否被执行过if(i==0){//判断第一个进程到达的时间是否等于系统时间,等于的话才开始执行第一个进程if(arr[i].getArriveTime()==systemTime){System.out.println("进程" + arr[i].getName() + "开始执行");//已经服务的时间和系统时间同步,应该在该时刻过去时增加,系统时间在程序末尾更新arr[i].setAlreadyServiceTime(arr[i].getAlreadyServiceTime() + 1);//更新已经服务的时间arr[i].setStartTime(systemTime);//记录进程i的开始服务时间arr[i].setVisited(1);//别忘记标记进程i被访问过,否则最后一个进程每次都会进入该if反复执行flag = 1;//标志当前有进程执行}}//以下为除第一个进程以外的进程,flag==0的时候只要 该进程到达了且未被访问则开始执行else {System.out.println("进程" + arr[i].getName() + "开始执行");//已经服务的时间和系统时间同步,应该在该时刻过去时增加,系统时间在程序末尾更新arr[i].setAlreadyServiceTime(arr[i].getAlreadyServiceTime() + 1);//更新已经服务的时间arr[i].setStartTime(systemTime);//记录进程i的开始服务时间arr[i].setVisited(1);//别忘记标记进程i被访问过,否则最后一个进程每次都会进入该if反复执行flag = 1;//标志当前有进程执行}}}systemTime++;//系统时间在程序末尾自动增加,表示该时刻过去//根据flag的值进行某时刻状态的记录if(flag==0){System.out.println("此时没有正在执行的进程");System.out.println("此时等待队列尾部没有进程");System.out.println("此时flag:" + flag);}else {System.out.println("此时正在执行进程i:" + i);System.out.println("此时等待队列尾部的是进程j:" + j);System.out.println("此时flag:" + flag);}if(i == num-1 && j == num-1 && flag == 0){ //当j=num-1时说明全部进程都已经到达系统,//当i=num-1并且flag=0时,表示本该在执行第num-1个进程,但是现在没有进程在执行//说明第num-1个进程即最后一个进程也执行完了,可以退出算法了break;}try{Thread.sleep(1000);//模拟系统运行,制造一个时间停顿}catch(Exception e){e.printStackTrace();}System.out.println();}displayResult();//算法执行结束,展示结果System.out.println("FCFS算法执行完成!");System.out.println();
}
2.短进程优先(SPF)算法
void run(){//*************************进入短进程优先算法(SPF)*************************////模拟一个系统时间,系统时间自动增加,当某进程的到达时间 等于 该时刻系统时间时,该进程进入等待队列int systemTime = 0;int i = 0;//正在运行的进程的下标,i的范围:i <= j//按照到达系统时间排序后,最后一个到达系统的进程的下标j,int j = -1;//下标从0到j的进程都在等待队列中,j的范围:0 <= j <= num-1,初始队列中无进程,则为-1int flag = 0;//用于判断系统现在是否被进程占用,flag=1时表示系统正在运行进程totalTurnaroundTime = 0;//初始化周转总时间totalTurnaroundTimeWithRight = 0;//初始化带权周转总时间quickSortArriveTime(arr, 0, num-1);//进入算法后先按照进程到达时间进行升序排序//*************************系统开始运行,开始执行进程*************************//System.out.println("短进程优先算法(SPF)开始运行");while(true){//模拟进程执行,从 系统时间为0开始 到 最后一个进程执行结束System.out.println("当前时间:" + systemTime);//当有进程到达系统时,记录该进程并输出提示信息//判断是否有进程进入系统(进入系统后进入等待队列),当有进程到达系统时,记录该进程并输出提示信息while(j+1 < num && systemTime == arr[j+1].getArriveTime()){//当该系统时间有到达的进程时,输出并记录进程到达系统,该判断独立执行,与flag无关//可能有多个进程同时到达,所以用while多次判断j++;System.out.println("进程" + arr[j].getName() + "到达系统");//短进程优先算法,每次有进程到达系统都要按照服务时间排序,将服务时间短的排在前面//等待队列中现在是下标从0到j-1的进程,队列都是已经到达的进程,所有只需要关注服务时间
// quickSortServiceTime(arr, 0, j-1);//按照服务时间从小到大升序排序//经测试发现,此处不能将arr排序,否则下面arr[i]指向的内容会变,选最短服务时间进程在下面遍历选择}//根据系统中是否有进程在执行,进行不同操作if(flag == 1){//flag=1表示 当前有进程在执行,判断该进程是否还在执行if(arr[i].getAlreadyServiceTime() !=arr[i].getServiceTime()){//如果进程i已经服务的时间 != 应该服务的时间,即进程正在执行,则输出"正在执行"System.out.println("进程" + arr[i].getName() + "正在执行");arr[i].setAlreadyServiceTime(arr[i].getAlreadyServiceTime() + 1);//更新已经服务的时间}else{//如果进程i已经服务的时间 = 应该服务的时间,即进程服务结束System.out.println("进程" + arr[i].getName() + "执行结束");arr[i].setEndTime(systemTime);//记录进程i结束服务时间//计算进程的周转时间、带权周转时间arr[i].setTurnaroundTime(arr[i].getEndTime() - arr[i].getArriveTime());arr[i].setTurnaroundTimeWithRight(arr[i].getTurnaroundTime() / (double)arr[i].getServiceTime());//记录周转总时间、带权周转总时间totalTurnaroundTime += arr[i].getTurnaroundTime();totalTurnaroundTimeWithRight += arr[i].getTurnaroundTimeWithRight();//此处不要令i加1了,找下一个需要执行的进程的任务交给flag=0的语句块,FCFS算法可以直接i+1,其他算法不可以
// if(i+1 <= j) i++;//执行完一个进程后,如果等待队列中还有进程,则i加1,准备执行下一个进程flag = 0;//进程执行完,flag置0,表明系统中无进程执行}}if(flag == 0)//此处不用else,因为上面flag=1时可能将flag置0,此flag=0和flag=1是可能都发生的{//flag=0表示 当前无进程在执行,如果等待队列中有进程,则执行一个进程//找到服务时间最小并且没有被执行的进程并执行它i = findMinServiceTimeIndex(j);//把拥有最小服务时间的进程下标赋值给i,然后执行if (arr[i].getVisited() == 0) { // 当前没有进程在执行 并且 进程i未被执行过,则执行进程i//此if判断是必要的,因为上方函数在找不到符合条件的进程时返回的i为0,//如果不执行if,则会反复执行进程num-1,导致算法陷入死循环if(i==0){if (arr[i].getArriveTime() == systemTime) {System.out.println("进程" + arr[i].getName() + "开始执行");arr[i].setAlreadyServiceTime(arr[i].getAlreadyServiceTime() + 1);//更新已经服务的时间arr[i].setStartTime(systemTime);//记录进程i的开始服务时间arr[i].setVisited(1);//别忘记标记进程i被访问过,否则最后一个进程每次都会进入该if反复执行flag = 1;//标志当前有进程执行}}else{System.out.println("进程" + arr[i].getName() + "开始执行");arr[i].setAlreadyServiceTime(arr[i].getAlreadyServiceTime() + 1);//更新已经服务的时间arr[i].setStartTime(systemTime);//记录进程i的开始服务时间arr[i].setVisited(1);//别忘记标记进程i被访问过,否则最后一个进程每次都会进入该if反复执行flag = 1;//标志当前有进程执行}}}systemTime++;//系统时间在程序末尾自动增加,表示该时刻过去if(flag==0){System.out.println("此时没有队列执行");System.out.println("此时等待队列尾部的是进程j:" + j);System.out.println("此时flag:" + flag);}if(flag==1) {System.out.println("此时正在执行进程i:" + i);System.out.println("此时等待队列尾部的是进程j:" + j);System.out.println("此时flag:" + flag);}//SPF算法不能单纯的再用这个if判断是否退出算法了(不是按到达时间顺序选取进程执行的算法都不行)//因为SPF算法不是按照FCFS一样从下标为0的进程顺序执行到下标为num-1的进程//最后一个执行的进程的下标不一定是num-1,所以不能用i=num-1来判断是否全部进程都执行完毕//但是为了此处退出算法的判断所有算法都统一,本人改写了最后给下标i赋值的代码,//当全部进程都执行完毕时,令i = num-1//使得该判断方式仍然成立,所以仍然使用此判断方式if(i == 0 && j == num-1 && flag == 0){//当j=num-1时说明全部进程都已经到达系统,//当i=0并且flag=0时,表示本该在执行第num-1个进程,但是现在没有进程在执行,所以i被自动初始化为0//说明第num-1个进程即最后一个进程也执行完了,可以退出算法了break;}try{Thread.sleep(1000);//模拟系统运行,制造一个时间停顿}catch(Exception e){e.printStackTrace();}System.out.println();}
3.静态级调度(SPSA)算法
//*************************进入静态优先级调度算法(SPSA)*************************//void run(){readPriority();//读入各进程的优先级//模拟一个系统时间,系统时间自动增加,当某进程的到达时间 等于 该时刻系统时间时,该进程进入等待队列int systemTime = 0;//初始化系统时间int i = 0;//设置正在运行的进程的下标,i的范围:i <= j//按照到达系统时间排序后,最后一个到达系统的进程的下标j,int j = -1;//下标从0到j的进程都在等待队列中,j的范围:0 <= j <= num-1,初始队列中无进程,则为-1int flag = 0;//用于判断系统现在是否被进程占用,flag=1时表示系统正在运行进程totalTurnaroundTime = 0;//初始化周转总时间totalTurnaroundTimeWithRight = 0;//初始化带权周转总时间quickSortArriveTime(arr, 0, num-1);//进入算法后先按照进程到达时间进行升序排序System.out.println("静态优先级调度算法(SPSA)开始运行");//系统开始运行while(true)//模拟进程执行,从系统时间为0开始 到 最后一个进程执行结束{System.out.println("当前时间:" + systemTime);//判断是否有进程进入系统(进入系统后进入等待队列),当有进程到达系统时,记录该进程并输出提示信息while(j+1 < num && systemTime == arr[j+1].getArriveTime()) //可能有多个进程同时到达,所以用while多次判断{j++;//当该系统时间有到达的进程时,输出并记录进程到达系统,该判断独立执行,与flag无关System.out.println("进程" + arr[j].getName() + "到达系统");}//根据系统中是否有进程在执行,进行不同操作if(flag == 1)//flag=1表示 当前有进程在执行,判断该进程是否还在执行{if(arr[i].getAlreadyServiceTime() != arr[i].getServiceTime()){//如果进程i已经服务的时间 != 应该服务的时间,即进程正在执行,则输出"正在执行"System.out.println("进程" + arr[i].getName() + "正在执行");arr[i].setAlreadyServiceTime(arr[i].getAlreadyServiceTime() + 1);//更新已经服务的时间}else{//如果进程i已经服务的时间 = 应该服务的时间,即进程服务结束System.out.println("进程" + arr[i].getName() + "执行结束");arr[i].setEndTime(systemTime);//记录进程i结束服务时间//计算进程的周转时间、带权周转时间arr[i].setTurnaroundTime(arr[i].getEndTime() - arr[i].getArriveTime());arr[i].setTurnaroundTimeWithRight(arr[i].getTurnaroundTime() / (double)arr[i].getServiceTime());//记录周转总时间、带权周转总时间totalTurnaroundTime += arr[i].getTurnaroundTime();totalTurnaroundTimeWithRight += arr[i].getTurnaroundTimeWithRight();//此处不要令i加1了,找下一个需要执行的进程的任务交给flag=0的语句块,FCFS算法可以直接i+1,其他算法不可以
// if(i+1 <= j) i++;//执行完一个进程后,如果等待队列中还有进程,则i加1,准备执行下一个进程flag = 0;//进程执行完,flag置0,表明系统中无进程执行}}if(flag == 0)//此处不用else,因为上面flag=1时可能将flag置0,此flag=0和flag=1是可能都发生的{//flag=0表示 当前无进程在执行,如果等待队列中有进程,则执行一个进程//找到拥有最大优先级并且没有被执行的进程并执行它i = findMaxPriorityIndex(j);//把拥有最大优先级的进程下标赋值给i,然后执行//if(i+1<=j) i++;if(arr[i].getVisited() == 0){//当 当前没有进程在执行 并且 进程i未被执行过//此if判断是必要的,因为上方函数在找不到符合条件的进程时返回的i为num-1,//如果不执行if,则会反复执行进程num-1,导致算法陷入死循环System.out.println("进程" + arr[i].getName() + "开始执行");arr[i].setAlreadyServiceTime(arr[i].getAlreadyServiceTime() + 1);//更新已经服务的时间arr[i].setStartTime(systemTime);//记录进程i的开始服务时间arr[i].setVisited(1);//别忘记标记进程i被访问过,否则最后一个进程每次都会进入该if反复执行flag = 1;//标志当前有进程执行}}systemTime++;//系统时间在程序末尾自动增加,表示该时刻过去if(flag==0){System.out.println("此时没有正在执行的进程");System.out.println("此时等待队列尾部没有进程");System.out.println("此时flag: "+flag);}else{System.out.println("此时正在执行进程i:" + i);System.out.println("此时等待队列尾部的是进程j:" + j);System.out.println("此时flag:" + flag);}//SPF算法不能单纯的再用这个if判断是否退出算法了(不是按到达时间顺序选取进程执行的算法都不行)//最后一个执行的进程的下标不一定是num-1,所以不能用i=num-1来判断是否全部进程都执行完毕//但是为了此处退出算法的判断所有算法都统一,本人改写了最后给下标i赋值的代码,//当全部进程都执行完毕时,令i = num-1//使得该判断方式仍然成立,所以仍然使用此判断方式if(i == num-1 && j == num-1 && flag == 0){//当j=num-1时说明全部进程都已经到达系统,//当i=num-1并且flag=0时,表示本该在执行第num-1个进程,但是现在没有进程在执行//说明第num-1个进程即最后一个进程也执行完了,可以退出算法了break;}try{Thread.sleep(1000);//模拟系统运行,制造一个时间停顿}catch(Exception e){e.printStackTrace();}System.out.println();}displayResult();//算法执行结束,展示结果System.out.println("SPSA算法执行完成!");System.out.println();}
4.轮转调度(RR)算法
void run()
{//进入时间片轮转算法(RR)quickSortArriveTime(arr, 0, num-1);//进入算法后先按照进程到达时间进行升序排序readTimeSlice();//读入设定的时间片的值int timeFlag = 0;//时间片计时变量,记录进程i已经执行的时间//模拟一个系统时间,系统时间自动增加,当某进程的到达时间 等于 该时刻系统时间时,该进程进入等待队列int systemTime = 0;int i = 0;//正在运行的进程的下标,i的范围:i <= j//按照到达系统时间排序后,最后一个到达系统的进程的下标j,int j = -1;//下标从0到j的进程都在等待队列中,j的范围:0 <= j <= num-1,初始队列中无进程,则为-1int flag = 0;//用于判断系统现在是否被进程占用,flag=1时表示系统正在运行进程totalTurnaroundTime = 0;//初始化周转总时间totalTurnaroundTimeWithRight = 0;//初始化带权周转总时间//系统开始运行,开始执行进程System.out.println("时间片轮转算法(RR)开始运行");while(true){//模拟进程执行,从 系统时间为0开始 到 最后一个进程执行结束System.out.println("当前时间:" + systemTime);//判断是否有进程进入系统(进入系统后进入等待队列),当有进程到达系统时,记录该进程并输出提示信息while(j+1 < num && systemTime == arr[j+1].getArriveTime()){//当该系统时间有到达的进程时,输出并记录进程到达系统//可能有多个进程同时到达,所以用while多次判断j++;System.out.println("进程" + arr[j].getName() + "到达系统");}//根据系统中是否有进程在执行,进行不同操作if(flag == 1){//flag=1表示 当前有进程在执行,判断该进程是否还在执行if(arr[i].getAlreadyServiceTime() != arr[i].getServiceTime()){//如果进程i已经服务的时间 != 应该服务的时间,即进程正在执行,则输出"正在执行"//如果该进程执行了一个时间片时间并且还未执行完毕,则将该进程放回等待队列,置flag=0,并重新计时//等到下一个系统时间时,在flag=0语句块中系统自动搜索下一个执行的进程,此处不要做多余操作if(timeFlag == timeSlice){//如果该进程执行了一个时间片时间并且还未执行完毕arr[i].setVisited(0);//将进程i置为未被执行过,放回等待队列flag = 0;//置当前无进程执行timeFlag = 0;//将时间片计时变量置0if(i+1 <= j) i++;//执行完一个进程后,如果等待队列中还有进程,则i加1,准备执行下一个进程else i = 0;//如果进程i后没有进程了,则令i = 0和flag}else{//如果该进程未执行够一个时间片,则继续执行System.out.println("进程" + arr[i].getName() + "正在执行");//已经服务的时间和系统时间同步,应该在该时刻过去时增加,系统时间在程序末尾更新arr[i].setAlreadyServiceTime(arr[i].getAlreadyServiceTime() + 1);//更新已经服务的时间timeFlag++;//记录进程i已经执行的时间 加1,该时间和 已经服务的时间 同步增加//上方部分代表该系统时刻进程已经执行完毕,此时可以判断该进程是否执行了一个时间片的时间}}else{//如果进程i已经服务的时间 = 应该服务的时间,即进程服务结束System.out.println("进程" + arr[i].getName() + "执行结束");arr[i].setEndTime(systemTime);//记录进程i结束服务时间//计算进程的周转时间、带权周转时间arr[i].setTurnaroundTime(arr[i].getEndTime() - arr[i].getArriveTime());arr[i].setTurnaroundTimeWithRight(arr[i].getTurnaroundTime() / (double)arr[i].getServiceTime());//记录周转总时间、带权周转总时间totalTurnaroundTime += arr[i].getTurnaroundTime();totalTurnaroundTimeWithRight += arr[i].getTurnaroundTimeWithRight();if(i+1 <= j) i++;//执行完一个进程后,如果等待队列中还有进程,则i加1,准备执行下一个进程else i = 0;//如果进程i后没有进程了,则令i = 0flag = 0;//进程执行完,flag置0,表明系统中无进程执行}}if(flag == 0)//此处不用else,因为上面flag=1时可能将flag置0,此flag=0和flag=1是可能都发生的{//flag=0表示 当前无进程在执行,如果等待队列中有进程,则执行一个进程i = findNextProcess(i, j);if(arr[i].getVisited() == 0){//当 等待队列中还有进程 并且 当前没有进程未被执行过//由于到达时间在最上面j的部分筛选过了,所以此处只需要筛选是否被执行过System.out.println("进程" + arr[i].getName() + "开始执行");//RR算法中,进程会多次执行,所以只有第一次执行,即已经服务的时间为0时才记录进程的开始时间if(arr[i].getAlreadyServiceTime() == 0) arr[i].setStartTime(systemTime); //记录进程i的开始服务时间//并且在RR算法中,记录开始服务时间要在记录已经服务时间前面,否则已经服务时间永不为0,则不会记录开始服务时间//已经服务的时间和系统时间同步,应该在该时刻过去时增加,系统时间在程序末尾更新arr[i].setAlreadyServiceTime(arr[i].getAlreadyServiceTime() + 1);//更新已经服务的时间arr[i].setVisited(1);//别忘记标记进程i被访问过,否则最后一个进程每次都会进入该if反复执行flag = 1;//标志当前有进程执行timeFlag++;}}systemTime++;//系统时间在程序末尾自动增加,表示该时刻过去if(flag==0){System.out.println("此时没有正在执行的进程");System.out.println("此时等待队列队尾没有进程");System.out.println("此时flag"+flag);// System.out.println("此时timeflag"+timeFlag);}else {System.out.println("此时正在执行进程i:" + i);System.out.println("此时等待队列尾部的是进程j:" + j);System.out.println("此时flag:" + flag);System.out.println("此时timeFlag:" + timeFlag);}if(i == num-1 && j == num-1 && flag == 0){//当j=num-1时说明全部进程都已经到达系统,//当i=num-1并且flag=0时,表示本该在执行第num-1个进程,但是现在没有进程在执行//说明第num-1个进程即最后一个进程也执行完了,可以退出算法了break;}try{Thread.sleep(1000);//模拟系统运行,制造一个时间停顿}catch(Exception e){e.printStackTrace();}System.out.println();}displayResult();//算法执行结束,展示结果System.out.println("RR算法执行完成!");System.out.println();}
3.程序设计
1)先来先服务(FCFS)算法








2)短进程优先算法






3)静态级优先调度算法











存入文档

4)时间片轮转算法







4.总结
选题是进程管理系统设计,由一个人独立完成从需求分析、结构设计、算法设计、运行测试、代码优化、实验总结六个部分,分别对FCFS算法,SPF算法,SPSA算法,RR算法进行设计。虽然实验程序仍然有所不足,但是在实验和设计的过程中也是收获颇丰,为以后的学习积累了经验。以下是每个算法的问题和解决方案以及心得:
先来先服务算法
①时间为0时没有进程到达但是进程已经开始执行,并且后面进程真正到达时又会执行一遍
②两个进程间如果有时间间隔并且间隔内没有进程在执行,则第二个进程不会等到到达才执行,且正在执行的进程i却也会显示和变化
③每个时间点的状态如果不判断,就算没有进程职系那个则一直会有显示正在执行的是该时刻进程的i
④等待队列进程增加了但是却不会继续执行下一个等待队列尾部的进程
短进程优先算法
1、在后期的调试中,发现第一个进程会在系统时间为0时开始执行,之后在设置好的开始时间又会执行一遍,后面在第一个进程中设定好需要系统时间等于开始时间才会执行后面的一系列代码;
2、进程有时候会死锁,在设置退出算法的条件时考虑的不全面。
静态优先级调度算法
在设计静态优先调度算法时,主要从以下方面考虑:
1. 考虑任务优先级:在实际应用中,任务的优先级可能会受到多个因素的影响,因此需要根据实际情况确定任务的优先级算法,出于这个考虑,在本次实验中我们可以根据考虑服务时间等因素自己设置系统的进程优先级,并设置了findMaxPriorityIndex()函数允许系统通过遍历自行找到最大优先级的进程。
2. 调度算法的实现:在实现调度算法时,需要考虑如何高效地对任务进行排序,并且需要保证算法的正确性和可靠性,故在该系统中设置quickSortArriveTime()使进程按到达时间升序排列。
3. 关于调度效率的优化:静态优先调度算法的调度效率可能会受到多个因素的影响,例如任务的数量、任务的执行时间等,因此我们需要针对不同的应用场景进行优化,以提高算法的调度效率,但在这一方面,在本次设计中,个人考虑或许不太全面,故在给出些许的程序可能在会出现些许问题,说明该设计还有优化的空间。
时间片轮转调度算法
非抢占式轮转调度算法RR中,系统根据FCFS策略,将所有就绪进程排成一个就绪队列。就绪队列上的每个进程每次仅运行一个时间片。时间片的选择对系统性能有很大影响。
若选择很小的时间片,将有利于短作业,但会增加系统开销;
若时间片选择太长,RR算法退化为FCFS算法,无法满足短作业和交互式用户的需求。
在调试程序过程中,出现了进程还未到达但已开始执行的问题。经分析,是等待队列的进程数量计算错误;发现周转时间输出为负数,是由于进程的执行顺序出错;发现由于进程在一个时间片时间后未执行完毕而出现多次执行,使得进程开始服务时间会被反复赋值,所以在记录开始服务时间代码处加上if条件判断,只记录进程第一次执行的开始服务时间。
相关文章:
操作系统课程设计:(JAVA)进程管理系统(附源码zip,jdk11,IDEA Ultimate2024 )
一.题目要求描述 本设计的目的是加深对进程概念及进程管理各部分内容的理解;熟悉进程管理中主要数据结构的设计及进程调度算法、进程控制机构、同步机构及通讯机构的实施。要求设计一个允许n个进程并发运行的进程管理模拟系统。 该系统包括有简单的进程控制、同步与…...
机器学习 | 回归算法原理——随机梯度下降法
Hi,大家好,我是半亩花海。接着上次的多重回归继续更新《白话机器学习的数学》这本书的学习笔记,在此分享随机梯度下降法这一回归算法原理。本章的回归算法原理还是基于《基于广告费预测点击量》项目,欢迎大家交流学习!…...
LeetCode 面试经典 150 题 | 位运算
目录 1 什么是位运算?2 67. 二进制求和3 136. 只出现一次的数字4 137. 只出现一次的数字 II5 201. 数字范围按位与 1 什么是位运算? ✒️ 源自:位运算 - 菜鸟教程 在现代计算机中,所有数据都以二进制形式存储,…...
postMessage 收到消息类型 “webpackWarnings“
场景描述: 当A系统中的parent页面使用iframe内嵌C系统的child页面,并且在parent页面中通过postMessageg给child页面发送消息时,如果C系统中使用了webpack,则webpack也会给child页面发送消息 ,消息类型为webpackWarnings。那么如何…...
计算机基础(day1)
1.什么是内存泄漏?什么是内存溢出?二者有什么区别? 2.了解的操作系统有哪些? Windows,Unix,Linux,Mac 3. 什么是局域网,广域网? 4.10M 兆宽带是什么意思?理论…...
cesium添加流动线
1:新建Spriteline1MaterialProperty.js文件 import * as Cesium from cesium;export function Spriteline1MaterialProperty(duration, image) {this._definitionChanged new Cesium.Event();this.duration duration;this.image image;this._time performance.…...
使用java自带的队列进行存取数据ArrayBlockingQueue 多线程读取ExecutorService
场景: 防止接收数据时处理不过来导致阻塞,使用ArrayBlockingQueue队列存储数据后,以多线程的方式处理数据 保证系统性能。 package com.yl.demo.main4;import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurr…...
【音视频之SDL2】Windows配置SDL2项目模板
文章目录 前言 SDL2 简介核心功能 Windows配置SDL2项目模板下载SDL2编译好的文件VS配置SDL2 测试代码效果展示 总结 前言 在开发跨平台的音视频应用程序时,SDL2(Simple DirectMedia Layer 2)是一个备受欢迎的选择。SDL2 是一个开源库&#x…...
JavaScript 里的深拷贝和浅拷贝
JavaScript 里的深拷贝和浅拷贝 JS中数据类型分为基本数据类型和引用数据类型。 基本类型值指的是那些保存在栈内存中的简单数据段。包含Number,String,Boolean,Null,Undefined ,Symbol。 引用类型值指的是那些保存…...
Oracle基础-集合
集合:两个结果集的字段个数和字段类型必须相同,才能使用集合操作。 --UNION 并集 重复行会去重 (SELECT A,B FROM DUAL UNION SELECT C,D FROM DUAL) UNION (SELECT A,B FROM DUAL UNION SELECT E,F FROM DUAL ); --UNION ALL 全集 包含所有记录 不去重…...
《浅谈如何培养树立正确的人工智能伦理观念》
目录 摘要: 一、引言 二、《机械公敌》的情节与主题概述 三、人工智能伦理与法律问题分析 1.伦理挑战 2.法律问题 四、培养正确的人工智能伦理观念的重要性 五、培养正确的人工智能伦理观念的途径与方法 1.加强教育与宣传 2.制定明确的伦理准则和规范 3.…...
uniapp实现局域网(内网)中APP自动检测版本,弹窗提醒升级
uniapp实现局域网(内网)中APP自动检测版本,弹窗提醒升级 在开发MES系统的过程中,涉及到了平板端APP的开发,既然是移动端的应用,那么肯定需要APP版本的自动更新功能。 查阅相关资料后,在uniapp的…...
【Golang 面试 - 进阶题】每日 3 题(六)
✍个人博客:Pandaconda-CSDN博客 📣专栏地址:http://t.csdnimg.cn/UWz06 📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞👍收藏…...
Unity横板动作游戏 -项目准备
项目准备 这是一篇 Unity 2022 最新稳定版本的教程同步笔记,本文将会讲解一些开始学习必须的条件。 安装环境 首先是安装 UnityHub,然后在 UnityHub 中安装 Unity 的版本(2022)。 只需要安装 开发者工具 和文档即可,导出到其他平台的工具等…...
基于Gunicorn + Flask + Docker的高并发部署策略
标题:基于Gunicorn Flask Docker的高并发部署策略 引言 随着互联网用户数量的增长,网站和应用程序需要能够处理越来越多的并发请求。Gunicorn 是一个 Python WSGI HTTP 服务器,Flask 是一个轻量级的 Web 应用框架,Docker 是一…...
jdk版本管理利器-sdkman
1.什么是sdkman? sdkman是一个轻量级、支持多平台的开源开发工具管理器,可以通过它安装任意主流发行版本(例如OpenJDK、Kona、GraalVM等等)的任意版本的JDK。通过下面的命令可以轻易安装sdkman: 2.安装 curl -s "https://…...
Kafka知识总结(事务+数据存储+请求模型+常见场景)
文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 事务 事务Producer保证消息写入分区的原子性,即这批消…...
C#中重写tospring方法
在C#中,重写ToString方法允许你自定义对象的字符串表示形式。当你想要打印对象或者在调试时查看对象的状态时,重写ToString方法非常有用。 默认情况下,ToString方法返回对象的类型名称。通过重写这个方法,你可以返回一个更有意义…...
【机器学习基础】机器学习的数学基础
【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈Python机器学习 ⌋ ⌋ ⌋ 机器学习是一门人工智能的分支学科,通过算法和模型让计算机从数据中学习,进行模型训练和优化,做出预测、分类和决策支持。Python成为机器学习的首选语言,…...
fastapi之零
FastAPI 详细介绍 FastAPI 是一个现代、快速(高性能)的 web 框架,用于构建 API。它基于标准的 Python 类型提示,使用 Starlette 作为 web 框架,Pydantic 进行数据验证和解析。以下是对 FastAPI 的详细介绍,…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
跨链模式:多链互操作架构与性能扩展方案
跨链模式:多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈:模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展(H2Cross架构): 适配层…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
