PSA 优先级调度算法 (抢占式)(java)

  • 处理机调度算法:Priority scheduling algorithm
    优先级调度算法(抢占式)
  • 运行结果
    在这里插入图片描述
    在这里插入图片描述
  • 流程图
    在这里插入图片描述

---------------------java代码------------------------

package operate;

import java.util.*;

/**
 * 优先级调度算法
 * 抢占式 (单处理机)
 * @author ymj
 * @Date: 2019/12/15 22:53
 */
public class PSA2 {


    static Scanner cin = new Scanner(System.in);

    /** 进程控制块 */
    static class PCB implements Comparable<PCB>{
        int id; // 进程id
        int arriveTime; // 到达时间
        int runTime; // 运行时间(要求服务时间)
        int hasRanTime = 0; // 已经运行时间, 初始值为0
        int PRI; // 优先级

        double responseRatio; // 响应比 = (等待时间 + 要求服务时间) / 要求服务时间
        int responseTime;// 响应时间 == 首次运行时间-到达时间

        int turnAroundTime; // 周转时间
        int waitTime; // 等待时间

        public PCB(int id, int arriveTime, int runTime, int PRI) {
            this.id = id;
            this.arriveTime = arriveTime;
            this.runTime = runTime;
            this.PRI = PRI;
        }

        @Override
        public int compareTo(PCB o) { // 按照 到达时间 进入就绪队列
            return  this.arriveTime - o.arriveTime;
        }
    }

    static PCB[] pcbs;
    /** 到达队列 */
    static Queue<PCB> queue = new PriorityQueue<>();

    /** 计算当前 进程响应比 */
    static void calculateResponseRatio(PCB pcb, int currentTime) {
        pcb.waitTime = currentTime+1 - pcb.arriveTime; // 等待时间
        pcb.responseRatio = (pcb.waitTime+pcb.runTime)*1.0/pcb.runTime;
    }

    /** 初始化 PCB 信息 */
    static void initPCB(){
        System.out.print("输入进程数: ");
        int num = cin.nextInt();
        pcbs = new PCB[num+1];
        System.out.println("输入  到达时间, 运行时间, 优先级");
        for(int i = 1; i <= num; i++) {
            System.out.print("进程" + i + ":");
            pcbs[i] = new PCB(i, cin.nextInt(), cin.nextInt(), cin.nextInt());
            queue.offer(pcbs[i]);
        }
    }

    /** 判断当前已经到达的进程, 判断进程的响应比 并使之进入就绪队列 */
    static boolean judge(Queue<PCB> readyQueue, int currentTime){
        boolean flag = false; // 为 true 表示 有 到达的进程
        while (true){
            PCB pcb = queue.peek(); // 最先到达的进程
            if (pcb == null){ // 所有进程都已经进入了就绪队列
                break;
            }else if(pcb.arriveTime <= currentTime){ // 当前有进程到达
                PCB runPCB = queue.poll();
                readyQueue.offer(runPCB); // 进入就绪队列 ---等待运行
                flag = true;
            }else { // 当前没有进程到达
                break;
            }
        }
        return flag;
    }

    /** 进程进入处理机运行, 如果进程运行结束返回 true*/
    static boolean processRun(PCB pcb, int currentTime){
        if(pcb.hasRanTime == 0){ // 进程首次运行时间
            pcb.responseTime = currentTime;
        }
        pcb.hasRanTime++; // 进入 处理机运行
        System.out.printf("  %d ", pcb.id);
        if(pcb.hasRanTime == pcb.runTime){ // 进程已经结束
            pcb.turnAroundTime = currentTime+1 - pcb.arriveTime;  // 周转时间
            pcb.waitTime = pcb.turnAroundTime - pcb.runTime; // 等待时间
            pcb.responseTime -= pcb.arriveTime;
            return true;
        }else {
            System.out.println();
            return false;
        }
    }

    /** 计算并打印 就绪队列中的进程 */
    static void printReadyProcess(Queue<PCB> queue, int currentTime){
        Iterator<PCB> iterator = queue.iterator();
        System.out.print(" 就绪队列 >> ");
        while (iterator.hasNext()) {
            PCB pcb = iterator.next();
            calculateResponseRatio(pcb, currentTime);
            System.out.printf("进程%d 优先级%d; ", pcb.id, pcb.PRI);
        }
        System.out.println();
    }

    /** 处理机运行 */
    static void run() {
        int currentTime = 0; // 当前时间
        if(!queue.isEmpty()){
            currentTime = queue.peek().arriveTime;
        }
        /** 定义就绪队列 , 根据作业长短  低-高 排序*/
        Queue<PCB> readyQueue = new PriorityQueue<PCB>(new Comparator<PCB>() {
            @Override
            public int compare(PCB o1, PCB o2) {
                if(o1.PRI != o2.PRI){
                    return (o2.PRI - o1.PRI) > 0 ? 1 : -1;
                }else {
                    return o1.arriveTime - o2.arriveTime;
                }
            }
        });

        PCB runPcb = null;
        System.out.println("now   正在运行的进程");
        while (true) {
            System.out.printf("%d\t ", currentTime);
            if(queue.isEmpty() && readyQueue.isEmpty() && runPcb == null){
                System.out.println("当前所有进程运行结束");
                break;
            }else{ // 进程进入 处理机运行

                if(judge(readyQueue, currentTime) == true) { // 此时有新到的进程
                    // 当前处理机 上的进程就要下处理机
                    if(runPcb != null) { // 处理机 占用中
                        readyQueue.offer(runPcb); //进入就绪队列
                        runPcb = null; // 此时处理机为 空闲
                    }
                }

                if(runPcb != null){ // 处理机上还有进程
                    /** 在 处理机中 运行 进程-->runPCB*/
                    if(processRun(runPcb, currentTime) == true){ // 运行后 进程已经结束
                        printReadyProcess(readyQueue, currentTime);
                        runPcb = null;
                    }
                }else { // 处理机空闲
                    runPcb = readyQueue.poll(); // 出就绪队列,
                    if(runPcb == null){ // 就绪队列为空, 意味着此时处理机空闲,而且没有到达的进程
                        currentTime++; // 处理机等待
                        System.out.printf("  处理机空闲,\n");
                        continue; // 进入下一轮
                    }else{ // 出就绪队列, 上处理机运行
                        if(processRun(runPcb, currentTime) == true){ // 运行后 进程已经结束
                            printReadyProcess(readyQueue, currentTime);
                            runPcb = null;
                        }
                    }
                }

                /** 时间片+1 */
                currentTime++;

            }
        }
    }

    public static void main(String[] args) {
        initPCB();
        System.out.println("-----处理机开始运行-----");
        run();
        System.out.println("-----处理机运行结束-----");
        showTurnAroundTime();
    }

    // 周转时间
    private static void showTurnAroundTime() {
        double averageT = 0;
        double averageWTAT = 0;
        double averageWT = 0;
        System.out.println("进程\t 周转时间\t 带权周转时间\t 等待时间\t");
        for (int i = 1; i < pcbs.length; i ++) {
            int turnAroundTime = pcbs[i].turnAroundTime;
            double weightTurnAroundTime = turnAroundTime*1.0/pcbs[i].runTime;
            int waitTime = pcbs[i].waitTime;
            System.out.printf("%d\t     %d\t\t\t  %.2f\t\t\t %d\n" ,i , turnAroundTime,  weightTurnAroundTime, waitTime);
            averageT += turnAroundTime;
            averageWTAT += weightTurnAroundTime;
            averageWT += waitTime;
        }
        averageT /= pcbs.length-1;
        averageWTAT /= pcbs.length-1;
        averageWT /= pcbs.length-1;
        System.out.println("平均周转时间:" + averageT);
        System.out.println("平均带权周转时间:" + averageWTAT);
        System.out.println("平均等待时间:" + averageWT);
    }

}

1. 实验目的 调度的实质是操作系统按照某种预定的策略来分配资源。进程调度的目的是分配CPU资源。由于进程调度程序执行的频率很高,因此调度算法的好坏直接影响到操作系统的性能。本实验的目的是编程模拟实现几种常用的进程调度算法,通过对几组进程分别使用不同的调度算法,计算进程的平均周转时间和平均带权周转时间,比较各种算法的性能优劣。 2. 实验原理 [1]. 进程调度算法描述 进程调度算法包括先来先服务调度算法、最短作业时间优先(抢占和非抢占)、最高响应比调度算法4种。(每个人必须做FCFS,然后在后面的三种中任选一种,即每个人必须做2种调度算法的模拟。) [2]. 衡量算法性能的参数 计算进程的平均周转时间和平均带权周转时间。 3. 实验内容 (1)编程实现本实验的程序,要求: [1]. 建立进程的进程控制块,进程控制块至少包括: a) 进程名称; b) 进程需要执行时间; c) 进入就绪队列时间; d) 进程执行开始时间 e) 进程执行结束时间 [2]. 编程实现调度算法。 [3]. 进程及相关信息的输入。这些信息可以直接从键盘上输入,也可以从文件读取。 [4]. 时间片与时间流逝的模拟。本实验需要对算法的执行计时,程序应该提供计算时间的方法。一种最简单的方法是使用键盘,比如每敲一次空格代表一个时间片的流逝。另一种方法是使用系统时钟。 [5]. 一组进程序列执行完毕,打印出结果信息。程序需要计算出每个进程的开始执行时间、结束时间、周转时间和带权周转时间,并为整个进程序列计算平均周转时间和平均带权周转时间。程序将计算结果按一定的格显示在计算机屏幕上或输出到文件中。打印出进程调度顺序图。 [6]. 实现数据在磁盘文件上的存取功能。 (2)对下列就绪进程序列分别使用上面的几种算法进行调度,计算每种算法下的平均周转时间和平均带权周转时间。 进程号 到达时间 要求执行时间 0 0 1 1 1 35 2 2 10 3 3 5 4 6 9 5 7 21 6 9 35 7 11 23 8 12 42 9 13 1 10 14 7 11 20 5 12 23 3 13 24 22 14 25 31
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值