PSA 優先級調度算法 (非搶占式)(java)


  • 處理機調度算法:Priority scheduling algorithm
    優先級調度算法
  • 運行結果
    在這里插入圖片描述
    在這里插入圖片描述
  • 流程圖
    在這里插入圖片描述

---------------------java代碼------------------------

package operate;

import java.util.*;

/** * 優先級調度算法 * 非搶占式 (完成) * 根據短作業優先算法 改編,只要將 就緒隊列 的判斷條件改為 《優先級》即可 * @author ymj * @Date: 2019/12/15 22:53 */
public class PSA {

    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();
// /** 計算當前 到達的進程 響應比 */
// calculateResponseRatio(runPCB, currentTime);
                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{ // 進程進入 處理機運行

                judge(readyQueue, currentTime);

                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);
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM