【操作系统】代码实践:先来先服务调度算法(FCFS),短进程优先调度算法(SJF),高响应比优先调度算法(HRRN)

文章目录

    • 一、实验需求
    • 二、需求分析
    • 三、效果展示
      • (1)FCFS 调度算法
      • (2)SJF 调度算法
      • (3)HRRN 调度算法
      • (4)综合对比
    • 四、具体代码

一、实验需求

设计一个有N个进程的进程调度程序,实现先来先服务调度算法,
,短进程优先调度算法,动态最高优先数优先调度算法。

二、需求分析

进程对象的信息抽象成此PCB类
【操作系统】代码实践:先来先服务调度算法(FCFS),短进程优先调度算法(SJF),高响应比优先调度算法(HRRN)_第1张图片
为PCB类编写常用Getter/Setter,构造方法(利用random随机数实现进程实际情况中的随机性),并模拟实现进程运行及阻塞时对应时间属性值的动态变化(自减1)等等。【操作系统】代码实践:先来先服务调度算法(FCFS),短进程优先调度算法(SJF),高响应比优先调度算法(HRRN)_第2张图片

1、FCFS算法最容易实现,因此只需判断当前时间time的值,是否等于进程序列中的第一个进程的到达时间即可,并不断输出当前时间和进程执行情况,例如其执行时间和剩余时间,最后再提示进程执行完毕,并输出周转时间,在序列中删除此进程结点等等。

2、其次是SJF算法,此算法需额外设置一个就绪进程序列,根据当前time值,将已经达到执行开始时间的进程放入进程的就绪队列,并删除在原进程序列中的此进程结点,模拟进程的状态变化与多队列机制,当就绪队列中有进程且数量不为一个时,则对此就绪队列的进程按照进程执行时间从小到大排序,并记录此次最优先进程(即最短进程的pid),则在下轮进行就绪进程队列的排序时,便可根据第一个队列中进程结点的pid是否为之前记录的pid得知进程是否被抢占,从而输出提示信息,进而输出其他信息。

3、最后,相对较麻烦的是HRRN算法,此算法,与SJF算法的实现类似,主要区别是,将SJF算法中就绪进程队列的排序依据,从进程执行时间最短,转为进程优先级最高,并额外再增加一个进程阻塞队列(根据实验要求),而阻塞队列也是根据阻塞的开始时间,与阻塞的过程时间来与当前time时间值进行判断的,因此,在SJF算法的基础上,HRRN算法的实现也就变的不再相对复杂,因此一开始声明的HRRN的复杂是相对于从0开始编写的复杂性。

三、效果展示

具体执行结果如下:
【操作系统】代码实践:先来先服务调度算法(FCFS),短进程优先调度算法(SJF),高响应比优先调度算法(HRRN)_第3张图片

(1)FCFS 调度算法

【操作系统】代码实践:先来先服务调度算法(FCFS),短进程优先调度算法(SJF),高响应比优先调度算法(HRRN)_第4张图片

(2)SJF 调度算法

【操作系统】代码实践:先来先服务调度算法(FCFS),短进程优先调度算法(SJF),高响应比优先调度算法(HRRN)_第5张图片

(3)HRRN 调度算法

(还为实现完整,这只是简单的优先级调度算法,优先数不具有动态变化性)
(内容较多,只截取部分)
【操作系统】代码实践:先来先服务调度算法(FCFS),短进程优先调度算法(SJF),高响应比优先调度算法(HRRN)_第6张图片

(4)综合对比

(情况随机,只截取一张图。其实此处只有HRRN算法中考虑了阻塞时间,而前两种算法并未考虑,因此,由于此变量不唯一,因此此情况下的比较也无意义,但可以直观地显示结果,也可以改进此程序代码,赋予其真正的意义)
【操作系统】代码实践:先来先服务调度算法(FCFS),短进程优先调度算法(SJF),高响应比优先调度算法(HRRN)_第7张图片

四、具体代码

class PCB {
    private int pid; // 进程id
    private int priority; // 进程优先级
    private int arrTime; // 到达时间
    private int allTime; // 还需运行时间
    private int cpuTime; // 已运行时间
    private int startBlockTime; // 开始阻塞时间
    private int blockTime; // 阻塞时间
    private String state; // 状态

    public PCB(int pid, int priority, int arrTime, int allTime, int cpuTime, int startBlockTime, int blockTime, String state) {
        this.pid = pid;
        this.priority = priority;
        this.arrTime = arrTime;
        this.allTime = allTime;
        this.cpuTime = cpuTime;
        this.startBlockTime = startBlockTime;
        this.blockTime = blockTime;
        this.state = state;
    }

    public int getPid() {
        return pid;
    }

    public void setPid(int pid) {
        this.pid = pid;
    }

    public int getPriority() {
        return priority;
    }

    public void setPriority(int priority) {
        this.priority = priority;
    }

    public int getArrTime() {
        return arrTime;
    }

    public void setArrTime(int arrTime) {
        this.arrTime = arrTime;
    }

    public int getAllTime() {
        return allTime;
    }

    public void setAllTime(int allTime) {
        this.allTime = allTime;
    }

    public int getCpuTime() {
        return cpuTime;
    }

    public void setCpuTime(int cpuTime) {
        this.cpuTime = cpuTime;
    }

    public int getStartBlockTime() {
        return startBlockTime;
    }

    public void setStartBlockTime(int startBlockTime) {
        this.startBlockTime = startBlockTime;
    }

    public int getBlockTime() {
        return blockTime;
    }

    public void setBlockTime(int blockTime) {
        this.blockTime = blockTime;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    /**
     * HRRN 执行情况模拟
     */
    public void show_HRRN() {
        System.out.println("进程:" + pid +
                        " 优先级:" + priority +
                        " 到达时间:" + arrTime +
                        " 还需运行时间:" + allTime +
                        " 已运行时间:" + cpuTime +
                        " 开始阻塞时间:" + startBlockTime +
                        " 阻塞时间:" + blockTime +
                        " 状态:" + state);
    }

    /**
     * SJF FCFS 执行情况模拟
     */
    public void show_SJF_FCFS() {
        System.out.println("进程:" + pid +
                "正在执行,到达时间:" + arrTime +
                " 还需运行时间:" + allTime +
                " 已运行时间:" + cpuTime);
    }

    public void toBlock() {
        state = "Block";
    }

    public void toRun() {
        state = "Run";
    }

    public void toFinish() {
        state = "Finish";
    }

    public void toReady() {
        state = "Ready";
    }

    public void running() { // 进程运行时的状态变化
        allTime -= 1;
        cpuTime += 1;
    }

    public void toStartBlock() { // 进程将要开始阻塞时的状态变化
        if (startBlockTime > 0) {
            startBlockTime -= 1;
        }
    }

    public void blocking() { // 进程阻塞时的状态变化
        if (blockTime > 0) {
            blockTime -= 1;
        }
        priority += 1;
    }
}

public class Main {
    /**
     * 初始化进程,生成四个进程并按到达时间讲它们放入列表 list
     * @param num
     */
    public static List<PCB> init(int num) {
        List<PCB> list = new ArrayList<PCB>();
        for (int i = 0; i < num; i++) {
            // 构造参数:进程id,优先级,到达时间,还需运行时间,
            // 已运行时间,开始阻塞时间,阻塞时间,状态
            list.add(new PCB(i, random(1, 10), random(1, 15), random(1, 10),
                    0, random(5, 10), random(1, 10), "Ready"));
        }

        // 将各进程按 到达时间 从小到大排列
        for (int i = 0; i < list.size() - 1; i++) {
            for (int j = i + 1; j < list.size(); j++) {
                if (list.get(i).getArrTime() > list.get(j).getArrTime()) {
                    PCB temp = list.get(i);
                    list.set(i, list.get(j));
                    list.set(j, temp);
                }
            }
        }
        return list;
    }

    public static int random(int m, int n) {
        Random random = new Random();
        return (int) Math.round(random.nextDouble() * n) + m;
    }

    /**
     * 先来先服务算法
     * @param list
     */
    public static int FCFS(List<PCB> list) {
        int time = 0;
        while (true) {
            System.out.println("time: " + time);
            PCB pcb = list.get(0);
            if (time >= pcb.getArrTime()) {
                pcb.running();
                pcb.show_SJF_FCFS();
                if (pcb.getAllTime() == 0) {
                    System.out.println("进程" + pcb.getPid() + "执行完毕,周转时间:" +
                            (time - pcb.getArrTime()) + "\n");
                    list.remove(list.get(0));
                }
            }
            time += 1;
            if (list.size() == 0) {
                return --time;
            }
        }
    }

    /**
     * 抢占式短作业优先
     * @param list
     */
    public static int SJF(List<PCB> list) {
        List<PCB> readyList = new ArrayList<PCB>(); // 就绪队列
        int time = 0;
        int pid = 0;
        while (true) {
            int readyListLength = readyList.size();
            System.out.println("time: " + time);

            if (list.size() > 0) {
                int i = 0;
                while (true) { // 将进程放入就绪队列,就绪队列的第一个是正在执行的进程
                    if (time == list.get(i).getArrTime()) {
                        readyList.add(list.get(i));
                        list.remove(list.get(i));
                        pid = readyList.get(0).getPid(); // 获取就绪队列第一个进程的ID
                        i -= 1;
                    }
                    i += 1;
                    if (i >= list.size()) {
                        break;
                    }
                }
            }

            if (readyList.size() >= 2 && readyList.size() != readyListLength) { // 判断就绪队列中最短的作业
                readyListLength = readyList.size();
                for (int i = 0; i < readyList.size() - 1; i++) {
                    for (int j = i + 1; j < readyList.size(); j++) {
                        if (readyList.get(i).getAllTime() > readyList.get(j).getAllTime()) {
                            PCB temp = readyList.get(i);
                            readyList.set(i, readyList.get(j));
                            readyList.set(j, temp);
                        }
                    }
                }
            }

            if (readyList.size() > 0) { // 执行进程
                if (pid != readyList.get(0).getPid()) { // 如果正在执行的进程改变,则发送抢占
                    System.out.println("发生抢占,进程" + readyList.get(0).getPid() + "开始执行");
                    pid = readyList.get(0).getPid();
                }
                readyList.get(0).running();
                readyList.get(0).show_SJF_FCFS();
                if (readyList.get(0).getAllTime() == 0) {
                    System.out.println("进程" + readyList.get(0).getPid() + "执行完毕,周转时间:" + (time - readyList.get(0).getArrTime() + 1));
                    readyList.remove(readyList.get(0));
                    if (readyList.size() > 0) {
                        pid = readyList.get(0).getPid();
                    }
                }
            }
            time += 1;
            if (readyList.size() == 0 && list.size() == 0) {
                break;
            }
        }
        return --time;
    }

    public static int HRRN(List<PCB> list) { // 动态最高优先数优先
        List<PCB> readyList = new ArrayList<PCB>(); // 就绪队列
        List<PCB> blockList = new ArrayList<PCB>(); // 阻塞队列
        int time = 0;
        int pid = 0;
        while (true) {
            System.out.println("time: " + time);
            if (list.size() > 0) {
                int i = 0;
                while (true) { // 将进程放入就绪队列
                    if (time == list.get(i).getArrTime()) {
                        readyList.add(list.get(i));
                        list.remove(list.get(i));
                        pid = readyList.get(0).getPid();
                        i -= 1;
                    }
                    i += 1;
                    if (i >= list.size()) {
                        break;
                    }
                }
            }

            for (int i = 0; i < readyList.size() - 1; i++) { // 将就绪队列的进程按优先级大小排列
                for (int j = i + 1; j < readyList.size(); j++) {
                    if (readyList.get(i).getPriority() < readyList.get(j).getPriority()) {
                        readyList.get(i).toReady();
                        PCB temp = readyList.get(i);
                        readyList.set(i, readyList.get(j));
                        readyList.set(j, temp);
                    }
                }
            }

            if (readyList.size() > 0) { // 执行过程
                if (pid != readyList.get(0).getPid()) {
                    System.out.println("发生抢占,进程" + readyList.get(0).getPid() + "开始执行");
                    pid = readyList.get(0).getPid();
                }
                if (readyList.get(0).getStartBlockTime() > 0 || readyList.get(0).getBlockTime() <= 0) {
                    readyList.get(0).toRun();
                    readyList.get(0).running();
                    readyList.get(0).toStartBlock();
                }
                for (int i = 1; i < readyList.size(); i++) {
                    readyList.get(i).setPriority(readyList.get(i).getPriority() + 1);
                    readyList.get(i).toStartBlock();
                }
            }

            if (blockList.size() > 0) { // 阻塞队列
                blockList.forEach(pcb -> {
                    pcb.blocking();
                });
            }

            readyList.forEach(pcb -> {
                pcb.show_HRRN();
            });

            blockList.forEach(pcb -> {
                pcb.show_HRRN();
            });

            if (readyList.size() > 0) { // 当进程开始阻塞事件为0,将进程放入阻塞队列
                int i = 0;
                while (true) {
                    if (readyList.size() > 0) {
                        if (readyList.get(i).getStartBlockTime() == 0 && readyList.get(i).getBlockTime() != 0) {
                            System.out.println("进程" + readyList.get(i).getPid() + "开始阻塞,进入阻塞队列");
                            readyList.get(i).toBlock();
                            blockList.add(readyList.get(i));
                            readyList.remove(readyList.get(i));
                            i -= 1;
                        }
                    }
                    i += 1;
                    if (i >= readyList.size()) {
                        break;
                    }
                }
            }

            if (blockList.size() > 0) {
                int i = 0;
                while (true) {
                    if (blockList.get(i).getBlockTime() == 0) {
                        System.out.println("进程" + blockList.get(i).getPid() + "阻塞结束,进入就绪队列");
                        blockList.get(i).toReady();
                        readyList.add(blockList.get(i));
                        blockList.remove(blockList.get(i));
                        pid = readyList.get(0).getPid();
                        i -= 1;
                    }
                    i += 1;
                    if (i >= blockList.size()) {
                        break;
                    }
                }
            }

            if (readyList.size() > 0) { // 进程执行完毕则移出就绪队列
                if (readyList.get(0).getAllTime() <= 0) {
                    readyList.get(0).toFinish();
                    System.out.println("进程" + readyList.get(0).getPid() + "执行完毕,周转时间: " +
                            (time - readyList.get(0).getArrTime() + 1) + ",状态:" + readyList.get(0).getState());
                    readyList.remove(readyList.get(0));
                    if (readyList.size() > 0) {
                        pid = readyList.get(0).getPid();
                    }
                }
            }

            time += 1;
            if (list.size() == 0 && readyList.size() == 0 && blockList.size() == 0) {
                break;
            }
        }
        return --time;
    }

    public static List<PCB> cloneList(List<PCB> list) {
        List<PCB> listClone = new ArrayList<PCB>();
        for (int i = 0; i < list.size(); i++) {
            PCB pcb = list.get(i);
            PCB pcbClone = new PCB(pcb.getPid(), pcb.getPriority(), pcb.getArrTime(), pcb.getAllTime(),
                    pcb.getCpuTime(), pcb.getStartBlockTime(), pcb.getBlockTime(), pcb.getState());
            listClone.add(pcbClone);
        }
        return listClone;
    }

    public static void main(String[] args) {
        while (true) {
            System.out.println("请选择算法:---------------");
            System.out.println("1、先来先服务");
            System.out.println("2、抢占式短作业优先");
            System.out.println("3、动态最高优先数优先");
            System.out.println("4、比较上述三种算法");
            System.out.println("------------------------");
            Scanner reader = new Scanner(System.in);
            System.out.print("请输入选项:");
            int select = reader.nextInt();
            switch (select) {
                case 1:
                    List<PCB> list = init(4);
                    list.forEach(pcb -> {
                        pcb.show_SJF_FCFS();
                    });
                    FCFS(list);
                    break;
                case 2:
                    List<PCB> list2 = init(4);
                    list2.forEach(pcb -> {
                        pcb.show_SJF_FCFS();
                    });
                    SJF(list2);
                    break;
                case 3:
                    List<PCB> list3 = init(4);
                    list3.forEach(pcb -> {
                        pcb.show_HRRN();
                    });
                    HRRN(list3);
                    break;
                case 4:
                    int time_FCFS = 0;
                    int time_SJF = 0;
                    int time_HRRN = 0;
                    List<PCB> list4 = init(4);
                    if (list4.size() > 0) {
                        List<PCB> list4_1 = cloneList(list4);
                        List<PCB> list4_2 = cloneList(list4);
                        List<PCB> list4_3 = cloneList(list4);
                        List<PCB> list4_all = cloneList(list4);
                        System.out.println("**************FCFS******************");
                        for (int i = 0; i < list4_1.size(); i++) {
                            list4_1.get(i).show_SJF_FCFS();
                        };
                        time_FCFS = FCFS(list4_1);
                        System.out.println("********************************");

                        System.out.println("****************SJF****************");
                        for (int i = 0; i < list4_2.size(); i++) {
                            list4_2.get(i).show_SJF_FCFS();
                        };
                        time_SJF = SJF(list4_2);
                        System.out.println("********************************");

                        System.out.println("*****************HRRN***************");
                        for (int i = 0; i < list4_3.size(); i++) {
                            list4_3.get(i).show_HRRN();
                        };
                        time_HRRN = HRRN(list4_3);
                        System.out.println("********************************");

                        System.out.println("=================情况综述======================");
                        System.out.println("=======进程情况========");
                        for (int i = 0; i < list4_all.size(); i++) {
                            list4_all.get(i).show_HRRN(); // 此方法的进程打印信息最全
                        };
                        System.out.println("FCFS 算法执行时间:" + time_FCFS);
                        System.out.println("SJF 算法执行时间:" + time_SJF);
                        System.out.println("HRRN 算法执行时间:" + time_HRRN);
                        System.out.println("=======================================");
                    }
                    break;
            }
        }
    }
}

【操作系统】代码实践:先来先服务调度算法(FCFS),短进程优先调度算法(SJF),高响应比优先调度算法(HRRN)_第8张图片

你可能感兴趣的:(算法,操作系统,java)