实验三  进程模拟调度实验

一、实验目的

多道系统中,当就绪进程数大于处理机数时,须按照某种策略决定哪些进程优先占用处理机,本实验模拟实现处理机调度,以加深了解处理机调度的工作

二、实验内容

选择一个调度算法,实现处理机调度。

三、实验要求

1、设计一个按下面三种调度算法实现处理机调度的程序。

1)先来先服务

2)短进程优先或优先权高优先

3)按时间片轮转

2、说明:PCB内容: 进程名/PID 、要求运行时间(单位时间)、优先权、状态 、到达时间、已用CPU时间等。

1) 可随机输入若干进程,并按优先权排序。

2) 从就绪选进程运行,优先权-1,要求运行时间=0时,撤消该进程。

3)每次调度后,显示各进程状态 。重新排序进行下轮调度。

本实验模是拟实现处理机调度,添加时要求写明该进程属性:进程名,运行时间,优先权等,然后按优先权排序,将具有最高优先权的进程的状态设为:运行,其他为:就绪,若优先权相同,则以其他原则决定,如:要求运行时间短的优先。

时间片轮转调度算法中,设定一个时间段T,在该时间段内,若该进程没运行完(即t>T),则中止该进程,优先权降一级,重新排序,修改状态。若在该时间段内运行完毕(即t<T),则当要求运行时间=0时,撤消该进程,然后重新排序,修改状态。所以,该界面应该每过一段时间更改一次,至于“要求时间”的修改可每过1秒修改一次。

程序主界面:

python模拟进程调度算法 进程调度模拟实验_java

 

图3-1 进程模拟调度流程图

四、实验报告

1、 可随机增加进程。

2、程序中使用的数据结构及符号说明。

3、一份源程序并附上注释。

4、要求附上程序模拟运行时的初值和运行结果。

1.代码部分(代码中有注释,就不另外说明):

三个类:

一个主类调用

一个process类

包含进程参数和调用方法

一个打印

打印主菜单和执行菜单

public class Main {
    public static void main(String[] args) {
//        进入系统
        int command=0;
        Scanner in=new Scanner(System.in);
        ArrayList<process> processes=new ArrayList<>();
        while (command!=4){
            PrintSth.menu();
            command=in.nextInt();
            if (command==1){
                System.out.println("请输入随机创建的进程的个数:");
                int temp=in.nextInt();
               processes= process.CreateProcesses(temp,processes);
            }
            else if (command==2){
                process.readProcess(processes);
            }
            else if(command==3){
                process.CancelProcess(processes);
            }
            else if(command==4){
               process.run(processes);
            }
            else if(command==5){
                return;
            }
            else {
                System.out.println("输入有误,重新输入!");
            }
        }
    }
}
//直接在这个包内创建这个类,避免弄混,以及简化一些代码
public class process {
    int id;//进程id
    String name;//进程名称
    int priority;//优先级最高为5,最低为1
    int size;//所占内存大小
    int time;//服务时间
    int arriveTime;//到达时间
    int exeTime;//执行时间
    int beginTime;//开始时间
    int finshTime;//完成时间
    int roundTime;//周转时间
    double aveRoundTime;//带权周转时间
    process(int id, String name, int priority, int size, int time, int arriveTime) {
        this.id = id;
        this.name = name;
        this.priority = priority;
        this.size = size;
        this.time = time;
        this.arriveTime = arriveTime;
        exeTime = 0;
    }
    public static ArrayList<process> CreateProcesses(int num, ArrayList<process> processes) {
        int id;
        String name;
        int priority = 5;
        int PCB;
        int time;
        int arriveTime;
        if (num > 0) {
            for (int i = 0; i < num; i++) {
                id = i + 1;
                name = "进程" + id;
                priority = (int) (5 * Math.random());
                if (priority == 0) {
                    while (priority == 0)
                        priority = (int) (5 * Math.random());
                }
                PCB = (int) (30 * Math.random());
                time = (int) (20 * Math.random());
                arriveTime = i;
                process process = new process(id, name, priority, PCB, time, arriveTime);
                processes.add(process);
            }
        } else {
            System.out.println("输入有误!请重新输入!");
        }
        return processes;
    }
    public static void readProcess(ArrayList<process> processes) {
        System.out.println("进程id    进程名     进程优先级     进程到达时间     进程运行时间       进程内存");
        for (int i = 0; i < processes.size(); i++) {
            System.out.println(
                    processes.get(i).id +
                            "        " + processes.get(i).name
                            + "          " + processes.get(i).priority
                            + "             " + processes.get(i).arriveTime
                            + "             " + processes.get(i).time
                            + "               " + processes.get(i).size);
        }
    }
    public static void CancelProcess(ArrayList<process> processes) {
        System.out.println("请输入要取消的进程的id:");
        Scanner in = new Scanner(System.in);
        int temp = in.nextInt();
        processes.remove(temp - 1);
    }
    public static void run(ArrayList<process> processes) {
//    为简化问题,这里的进程到达时间令它为与id相同时间
        PrintSth.excutionmenu();
        Scanner in = new Scanner(System.in);
        int c = in.nextInt();
        while (c!= 5) {
            if (c == 1) {
                FCFS(processes);
            } else if (c == 2) {
                SJF(processes);
            } else if (c == 3) {
                System.out.println("请输入时间片大小:");
                int q =in.nextInt();
                RR(processes,q);
            } else if (c == 4) {
                HRN(processes);
            } else if (c == 5) {
                return;
            } else System.out.println("输入错误,请重新输入!");
            PrintSth.excutionmenu();
            c = in.nextInt();
        }
    }
    public static void FCFS(ArrayList<process> processes) {
        System.out.println("先来先服务算法:");
        Queue<process> endQueue = new LinkedList<>();
        Queue<process> readyQueue = new LinkedList< >();
        int time = 0;
        int size;
        double total = 0;
        System.out.println(time + "s:");
        while (endQueue.size() < processes.size()) {
//            是否有队列到达
            for (int i = 0; i < processes.size(); i++) {
//                控制进程到达准备队列
                if (processes.get(i).arriveTime == time) {
                    readyQueue.add(processes.get(i));
                    processes.get(i).beginTime = time;
                    System.out.println("进程" + i + "到达");
                }
            }
            //                进程执行
            process process = readyQueue.peek();
            System.out.println("进程" + process.id + "执行");
            if (process.exeTime == process.time) {
                process = readyQueue.poll();
                endQueue.offer(process);
                process.roundTime = time - process.arriveTime;
                process.finshTime = time;
                process.aveRoundTime = (process.roundTime + 0.0) / process.exeTime;
                System.out.println("进程" + process.id + "执行完成");
            }
            time++;
            process.exeTime++;
            System.out.println(time + "s:");
            //执行结束
            if (readyQueue.isEmpty()) {
                size = endQueue.size();
                for (process p : endQueue) {
                    total = total + p.aveRoundTime;
                    System.out.println("进程:" + p.id + "\t完成时间:\t" + p.finshTime
                            + "\t周转时间:\t" + p.roundTime + "带权周转时间:\t" + p.aveRoundTime + "\n");
                }
                System.out.println("平均带权周转时间:\t" + (total / size));
            }
        }
    }
    public static void RR(ArrayList<process> processes,int q) {
        Queue<process> endQueue = new LinkedList<>();
        Queue<process> readyQueue = new LinkedList<>();
        boolean flag=false;
        int time = 0;
        int size;
        double total = 0;
        System.out.println(time + "s:");
        while(endQueue.size()<processes.size()){
            //            是否有队列到达
//            按时间片执行
            for (int i = 0; i < q; i++) {
                for (int j = 0; j < processes.size(); j++) {
//                控制进程到达准备队列
                    if (processes.get(j).arriveTime == time) {
                        readyQueue.add(processes.get(j));
                        processes.get(j).beginTime = time;
                        System.out.println("进程" + j + "到达");
                    }
                }
                process process = readyQueue.peek();
                System.out.println("进程" + process.id + "执行");
                time++;
                process.exeTime++;
                //进程完成
                if (process.exeTime == process.time) {
                    process = readyQueue.poll();
                    endQueue.offer(process);
                    process.roundTime = time - process.arriveTime;
                    process.finshTime = time;
                    process.aveRoundTime = (process.roundTime + 0.0) / process.exeTime;
                    System.out.println("进程" + process.id + "执行完成");
                    break;
                }
                process pro = null;
                if (i == q - 1 && !flag && !readyQueue.isEmpty()) {
                    pro = readyQueue.poll();
                    System.out.println("  进程" + pro.id + "在该时间片内未完成, 中断执行");
                }
                System.out.println(time + "s: ");
                if (pro != null) {
                    readyQueue.offer(pro);
                }
            }
            if (readyQueue.isEmpty()) {
                size = endQueue.size();
                for (process p : endQueue) {
                    total = total + p.aveRoundTime;
                    System.out.println("进程:" + p.id + "\t完成时间:\t" + p.finshTime
                            + "\t周转时间:\t" + p.roundTime + "带权周转时间:\t" + p.aveRoundTime + "\n");
                }
                System.out.println("平均带权周转时间:\t" + (total / size));
            }
        }
    }
    public static void HRN(ArrayList<process> processes) {
        Queue<process> endQueue = new LinkedList<>();
        ArrayList<process> readyList = new ArrayList<>();
        int time = 0;
        int size;
        double total = 0;
        boolean flag = false;
        process process = null;
        System.out.println(time + "s:");
        while (endQueue.size() < processes.size()) {
//            是否有队列到达
            for (int i = 0; i < processes.size(); i++) {
//                控制进程到达准备队列
                if (processes.get(i).arriveTime == time) {
                    processes.get(i).beginTime = time;
                    System.out.println("进程" + (i+1) + "到达");
                    readyList.add(processes.get(i));
                    //使用冒泡排序,将进入数组中的进程按优先级排序
                    Sort.HRNSort(readyList,time);
                }
            }
            //                进程执行
            if (!flag) {
                process = readyList.get(0);
                readyList.remove(0);
            }
            System.out.println("进程" + process.id + "执行");
            flag = true;
            //进程执行完成
            if (process.exeTime == process.time) {
                endQueue.offer(process);
                process.roundTime = time - process.arriveTime;
                process.finshTime = time;
                process.aveRoundTime = (process.roundTime + 0.0) / process.exeTime;
                System.out.println("进程" + process.id + "执行完成");
                flag = false;
            }
            time++;
            process.exeTime++;
            System.out.println(time + "s:");
            //执行结束
            if (readyList.isEmpty() & flag == false) {
                size = endQueue.size();
                for (process p : endQueue) {
                    total = total + p.aveRoundTime;
                    System.out.println("进程:" + p.id + "\t进程优先级:\t" + p.priority + "\t完成时间:\t" + p.finshTime
                            + "\t周转时间:\t" + p.roundTime +
                            "\t带权周转时间:\t" + p.aveRoundTime + "\n");
                }
                System.out.println("平均带权周转时间:\t" + (total / size));
                return;
            }
        }
    }
    public static void SJF(ArrayList<process> processes) {
        Queue<process> endQueue = new LinkedList<>();
        ArrayList<process> readyList = new ArrayList<>();
        int time = 0;
        int size;
        double total = 0;
        boolean flag = false;
        process process = null;
        System.out.println(time + "s:");
        while (endQueue.size() < processes.size()) {
//            是否有队列到达
            for (int i = 0; i < processes.size(); i++) {
//                控制进程到达准备队列
                if (processes.get(i).arriveTime == time) {
                    processes.get(i).beginTime = time;
                    System.out.println("进程" + (i+1) + "到达");
                    readyList.add(processes.get(i));
                    //使用冒泡排序,将进入数组中的进程按优先级排序
                    Sort.BubbleSort(readyList);
                }
            }
            //                进程执行
            if (!flag) {
                process = readyList.get(0);
                readyList.remove(0);
            }
            System.out.println("进程" + process.id + "执行");
            flag = true;
            //进程执行完成
            if (process.exeTime == process.time) {
                endQueue.offer(process);
                process.roundTime = time - process.arriveTime;
                process.finshTime = time;
                process.aveRoundTime = (process.roundTime + 0.0) / process.exeTime;
                System.out.println("进程" + process.id + "执行完成");
                flag = false;
            }
            time++;
            process.exeTime++;
            System.out.println(time + "s:");
            //执行结束
            if (readyList.isEmpty() & flag == false) {
                size = endQueue.size();
                for (process p : endQueue) {
                    total = total + p.aveRoundTime;
                    System.out.println("进程:" + p.id + "\t进程优先级:\t" + p.priority + "\t完成时间:\t" + p.finshTime
                            + "\t周转时间:\t" + p.roundTime +
                            "\t带权周转时间:\t" + p.aveRoundTime + "\n");
                }
                System.out.println("平均带权周转时间:\t" + (total / size));
                return;
            }
        }
    }
}
public class Sort {
public static void BubbleSort(ArrayList<process> processes){
    if(processes==null||processes.size()<2)
        return;
    for (int i = processes.size()-1; i >0; i--) {
        for (int j = 0; j < i; j++) {
            if(processes.get(j).priority<processes.get(j+1).priority){
                Collections.swap(processes,j,j+1);
            }
        }
    }
}
public static void HRNSort(ArrayList<process> processes,int now){
    if (processes==null||processes.size()<2)
        return;
    float first= (processes.get(0).time+now-processes.get(0).arriveTime)/processes.get(0).time;
    for (int i = processes.size()-1; i >0; i--) {
        float power=(processes.get(i).time+now-processes.get(i).arriveTime)/processes.get(i).time;
        if(first<power)
            Collections.swap(processes,0,i);
    }
}
public class PrintSth {
    public static void menu(){
        System.out.println("|-------------------------------------------------------|\n");
        System.out.println("|模拟进程执行小程序:                                     |\n");
        System.out.println("|1.创建进程                                             |\n");
        System.out.println("|2.查看现有进程                                          |\n");
        System.out.println("|3.撤销进程                                             |\n");
        System.out.println("|4.执行进程                                             |\n");
        System.out.println("|5.退出进程                                             |\n");
        System.out.println("|------------------------------------------------------|\n");
        System.out.println("请输入操作指令:\n");
    }
    public static void excutionmenu(){
        System.out.println("执行选项:\n");
        System.out.println("1.先来先服务\n");
        System.out.println("2.短线程优先\n");
        System.out.println("3.时间片轮转调度\n");
        System.out.println("4.高响应比有先调度\n");
        System.out.println("5.返回到上一步\n");
        System.out.println("请选择运行的方式:");
    }
    public static void  excution(){
        System.out.println(
                //打印正在执行的进程信息
                "进程名称"+"进程到达时间:"+"进程状态:"+"进程剩余执行时间:");
    }
    public static void excutionlist(){
        System.out.println("进程列表:");
        System.out.println("进程名:"+"进程状态:"+"进程到达时间"+"进程执行时间");
    }
}

2.运行截图

主菜单

执行菜单:

python模拟进程调度算法 进程调度模拟实验_System_02

 

(1)先来先服务:

a.随机生成测试数据:

python模拟进程调度算法 进程调度模拟实验_python模拟进程调度算法_03

 

b.运行过程的部分动态演示

python模拟进程调度算法 进程调度模拟实验_运行时间_04

   

 

c.运行结果

python模拟进程调度算法 进程调度模拟实验_System_05

 

python模拟进程调度算法 进程调度模拟实验_java_06

 

python模拟进程调度算法 进程调度模拟实验_进程名_07

 

(2)短进程优先

a.测试数据

b.动态演示部分截图

 

c.运行结果图

(3)轮转法

a.测试数据

b.动态演示:

c.运行结果

(4)最高响应比优先

a.测试数据

b.动态演示:

 

c.运行结果