操作系统课程设计:(JAVA)进程管理系统(附源码zip,jdk11,IDEA Ultimate2024 )

news2024/11/28 8:42:24

一.题目要求描述

   本设计的目的是加深对进程概念及进程管理各部分内容的理解;熟悉进程管理中主要数据结构的设计及进程调度算法、进程控制机构、同步机构及通讯机构的实施。要求设计一个允许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,初始队列中无进程,则为-1
    int 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,初始队列中无进程,则为-1
        int 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,初始队列中无进程,则为-1
       int 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,初始队列中无进程,则为-1
    int 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;//将时间片计时变量置0

                    if(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 = 0
                flag = 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条件判断,只记录进程第一次执行的开始服务时间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1961627.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一行代码教你使用Python制作炫酷二维码

二维码&#xff0c;我们日常生活中随处可见的编码方式&#xff0c;凭借其方便快捷的信息承载能力&#xff0c;已经渗透到各行各业。 MyQR 的介绍 MyQR 是一个 Python 库&#xff0c;用于生成自定义二维码&#xff0c;包括带有 Logo、彩色和动态的二维码。它基于 Python 的 qr…

【基础篇】Docker 镜像管理 THREE

嘿&#xff0c;小伙伴们&#xff01;我是小竹笋&#xff0c;一名热爱创作的工程师。在上一篇文章中&#xff0c;我们探讨了 Docker 的架构与关键组件。今天&#xff0c;让我们一起深入了解一下 Docker 镜像管理的相关知识吧&#xff01; &#x1f4e6; 创建和管理镜像 镜像是…

Qt程序移植至Arm开发板

环境准备&#xff1a; 系统调试工具SecureCRT SecureCRT 是一款支持 SSH 协议的终端仿真软件&#xff0c;可通过串口或网口对评估板系统信息进行查看、对评估板系统进行调试等。 SecureCRT的安装破解 [详细过程2024]-CSDN博客https://blog.csdn.net/2301_76659937/article/det…

2-50 基于matlab的遗传模拟退火算法的聚类算法

基于matlab的遗传模拟退火算法的聚类算法&#xff0c;以模糊K-均值聚类算法为基础&#xff0c;对各样本的聚类中心进行优化&#xff0c;输出聚类可视化结果。聚类类别数可自由输入。程序已调通&#xff0c;可直接运行。 2-50 遗传模拟退火算法的聚类算法 - 小红书 (xiaohongshu…

【源码阅读】Redisson lock源码

Redisson 加锁非常简单&#xff0c;还支持 redis 单实例、redis 哨兵、redis cluster、redis master-slave 等各种部署架构 RLock lock redisson.getLock("cyk-test"); lock.lock(); lock.unlock(); 底层原理 加锁机制 废话不多说&#xff0c;直接看源码&#xf…

Go语言----flag包(导入、配置、以及常用方法Parse()、Parsed()、NArg())

在 Go语言中有很多种方法来处理命令行参数。如果我们只是想简单的获取命令行的参数&#xff0c;可以像Go语言–延迟调用defer、获取命令行参数、局部变量以及全局变量中介绍的不使用任何库&#xff0c;直接使用 os.Args&#xff1b; d但是 Golang 的标准库提供了 flag 包来处理…

机械拆装-基于Unity-本地数据持久化

目录 1. 数据结构简介&#xff1a;数据的集合 1.1 线性数据结构 1.2 非线性数据结构 2. 对数据集合的操作&#xff1a; 3. 数据持久化 3.1 数据的序列化存储 3.2 JSON文件硬盘存储 3.2.1 Json文件允许存储的数据类型 3.2.2 Json文件的语法格式 3.2.3 Json文件的读取 3.2.4 …

Echarts toolbox相关配置 dataZoom缩放

前言:最近开发遇到一个echarts相关问题,需要实现用户鼠标滚动实现图表缩放,或者实现选中某一段区域进行缩放,放大效果; 1.第一个需求就是区域缩放按钮要隐藏掉,用户鼠标放在图表内就默认实现选择效果,并且区域缩放还原按钮不能隐藏,需要在初始化配置这三个属性. // 假设你已经…

孙宇晨建议中国重新考虑“比特币政策”!中美竞争将使加密货币行业受益?美国对“中国崛起”感到焦虑!

近日&#xff0c;前美国总统特朗普发表了一番振奋人心的比特币演讲&#xff0c;令加密货币社群反响热烈。而Tron区块链创始人孙宇晨则建议中国重新考虑其对于比特币的政策立场&#xff0c;并指出中美两国在加密货币领域的竞争&#xff0c;将使整个行业受益。这再次引发了人们对…

未来社交:Facebook如何定义虚拟现实的新时代?

随着科技的飞速发展&#xff0c;虚拟现实&#xff08;VR&#xff09;逐渐从科幻小说中的幻想变成了现实生活中的前沿技术。在这一领域&#xff0c;Facebook&#xff08;现已更名为Meta&#xff09;扮演了重要角色&#xff0c;通过不断的创新和投资&#xff0c;致力于打造一个全…

花几千上万学习Java,真没必要!(三十六)

1、File类&#xff1a; 测试代码1&#xff1a; package filetest.com; import java.io.File; import java.io.IOException; public class FileOperations { public static void main(String[] args) { // 创建新文件File file new File("example.txt"); tr…

18966 两两配对差值最小

这个问题可以通过排序和配对来解决。首先&#xff0c;我们将数组排序&#xff0c;然后我们将数组的第一个元素和最后一个元素配对&#xff0c;第二个元素和倒数第二个元素配对&#xff0c;以此类推。这样&#xff0c;我们可以得到n/2个和&#xff0c;然后我们找出这些和中的最大…

光伏可行性研究报告能否自动生成?

随着技术的不断进步和应用的广泛普及&#xff0c;光伏项目的规划与实施也面临着更加复杂多变的考量因素&#xff0c;其中&#xff0c;光伏可行性研究报告成为了项目前期不可或缺的重要内容。那么&#xff0c;面对这一需求&#xff0c;光伏可行性研究报告能否实现自动生成呢&…

Nat Med·UNI:开启计算病理学新篇章的自监督基础模型|顶刊精析·24-07-31

小罗碎碎念 本期推文主题 这一期推文是病理AI基础模型UNI的详细介绍&#xff0c;原文如下。下期推文会介绍如何使用这个模型&#xff0c;为了你能看懂下期的推文&#xff0c;强烈建议你好好看看今天这期推文。 看完这篇推文以后&#xff0c;你大概就能清楚这个模型对自己的数据…

搞懂数据结构与Java实现

文章链接&#xff1a;搞懂数据结构与Java实现 (qq.com) 代码链接&#xff1a; Java实现数组模拟循环队列代码 (qq.com) Java实现数组模拟栈代码 (qq.com) Java实现链表代码 (qq.com) Java实现哈希表代码 (qq.com) Java实现二叉树代码 (qq.com) Java实现图代码 (qq.com)

《计算机网络》(第8版)考研真题

第一章 一、选择题 1 在 TCP/IP 体系结构中,直接为 ICMP 提供服务的协议是( )。[2012 年统考] A .PPP B .IP C .UDP D .TCP 【答案】B 【解析】A 项:PPP 在 TCP/IP 体系结构中属于网络接口层协议(在 ISO/OSI 体系结构中属于数据链路层协议),所以 PPP 为网络层提供…

免费【2024】springboot 厨房达人美食分享平台

博主介绍&#xff1a;✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术范围&#xff1a;SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化…

图片格式转换教程:百种格式随意转换,建议收藏使用!

图片格式转换方法有哪些&#xff1f;本文整理了几款好用且简单的格式转换工具&#xff0c;适用于处理各种图片格式转换的难题。 常见的图片格式转换有png转换为jpg、heic转jpg、webp转jpg等&#xff0c;特别是heic、webp、这两种图片格式&#xff0c;格式比较特殊&#xff0c;兼…

《最新出炉》系列入门篇-Python+Playwright自动化测试-57- 上传文件 - 番外篇

软件测试微信群&#xff1a;https://bbs.csdn.net/topics/618423372 有兴趣的可以扫码加入 1.简介 前边的三篇文章基本上对文件上传的知识介绍和讲解的差不多了&#xff0c;今天主要是来分享宏哥在文件上传的实际操作中发现的一个问题&#xff1a;input控件和非input控件的上…

打破技术壁垒,加速企业数字化转型:低代码平台如何降低开发门槛

科技飞速发展&#xff0c;企业数字化转型趋势不可逆转。数字化转型不仅能够优化内部运营流程&#xff0c;提升管理效率&#xff0c;还能通过数据驱动决策&#xff0c;增强市场竞争力。传统开发模式因技术门槛、周期长&#xff0c;限制了企业创新与响应速度。 低代码平台应运而生…