Java 實現--時間片輪轉 RR 進程調度算法


時間片輪轉(Round-Robin)調度算法是操作系統一種比較公平的進程調度的方式,這種方式使得就緒隊列上的所有進程在每次輪轉時都可以運行相同的一個時間片。

基本原理

算法實現原理是,按進程到達順序(FCFS 原則)將進程依次加入就緒隊列當中,然后將 CPU 分配給位於隊首的進程,確定一個時間片,讓該進程執行一個時間片。當該進程執行時間到時,該進程可能已經執行完畢(可能在時間片未到時就以及執行完畢),或者未執行完畢,如果是前者只需將進程彈出隊列即可,如果是后者則將該進程加入隊尾,並將 CPU 分配給新的隊首進程,如此循環。

進程切換時機

進程在執行時分為兩種情況

  • 在該時間片內進程執行完畢,這種情況調度程序將立即把該進程彈出隊列,並把 CPU 分配給新的隊首進程
  • 在該時間片內進程未執行完畢,調度程序將立即中斷該進程執行,把該進程加入隊尾,並將 CPU 分配給新的隊首進程

時間片大小的確定

在 RR 算法中,時間片的大小直接影響了系統的性能。

  • 時間片過小,有利於短作業,但是會頻繁地切換進程,增加了系統的開銷,影響性能。
  • 時間片過大,算法退化成 FCFS 算法,如果某個短作業進程之前的進程都是長作業,將導致后面的短作業進程長時間等待。

有關的計算

  • 周轉時間 = 進程完成時間 - 進程到達時間
  • 帶權周轉時間 = 進程周轉時間 / 進程實際運行時間
  • 平均周轉時間 = (進程1周轉時間 + ... + 進程n周轉時間)/ n
  • 平均帶權周轉時間 = (進程1帶權周轉時間 + ... + 進程n帶權周轉時間)/ n

實現

package cn.vecrates.operatingSystem;

import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;

public class RR { private int mProcessCount; //進程數 private Queue<Process> mReadyQueue; //就緒隊列,存放“待運行的進程 private Queue<Process> mUnreachQueue; //存放“到達時間未到的進程” private int mTimeSlice; //時間片 private Queue<Process> mExecutedQueue; //執行完畢的進程隊列 private double mTotalWholeTime = 0.0; private double mTotalWeightWholeTime = 0.0; private RR(int processCount, Queue<Process> processQueue, int timeSlice) { this.mProcessCount = processCount; this.mUnreachQueue = processQueue; mReadyQueue = new LinkedBlockingQueue<>(); this.mTimeSlice = timeSlice; mExecutedQueue = new LinkedList<>(); } /** * RR 算法實現 */ public void RRAlgorithm() { mReadyQueue.add(mUnreachQueue.poll()); Process currProcess = mReadyQueue.poll(); //第一個進程執行 int currTime = executeProcess(currProcess, 0); while(!mReadyQueue.isEmpty() || !mUnreachQueue.isEmpty()) { //把所有“到達時間”達到的進程加入運行隊列頭部 while(!mUnreachQueue.isEmpty()) { if(mUnreachQueue.peek().getArrivalTime() <= currTime) { mReadyQueue.add(mUnreachQueue.poll()); } else { break; } }java學習群669823128 if(currProcess.getRemainServiceTime() > 0) mReadyQueue.add(currProcess); //運行隊列不為空時 if(!mReadyQueue.isEmpty()) { currProcess = mReadyQueue.poll(); currTime = executeProcess(currProcess, currTime); } else { //當前沒有進程執行,但還有進程為到達,時間直接跳轉到到達時間 currTime = mUnreachQueue.peek().getArrivalTime(); } } } private int executeProcess(Process currProcess, int currTime) { if(currProcess.getRemainServiceTime() - mTimeSlice <= 0) { //當前進程在這個時間片內能執行完畢 showExecuteMessage(currTime, currTime += currProcess.getRemainServiceTime(), currProcess.getName()); currProcess.setFinishTime(currTime); currProcess.setRemainServiceTime(0); //對周轉時間等進行計算 calculeteWholeTime(currProcess); calculateWeightWholeTime(currProcess); mTotalWholeTime += currProcess.getWholeTime(); mTotalWeightWholeTime += currProcess.getWeightWholeTime(); mExecutedQueue.add(currProcess); } else { //不能執行完畢 showExecuteMessage(currTime, currTime += mTimeSlice, currProcess.getName()); currProcess.setRemainServiceTime(currProcess.getRemainServiceTime() - mTimeSlice); } return currTime; } /** * 計算周轉時間 * @param process */ private void calculeteWholeTime(Process process) { process.setWholeTime(process.getFinishTime() - process.getArrivalTime()); } /** * 計算帶權周轉時間 * @param process */ private void calculateWeightWholeTime(Process process) { process.setWeightWholeTime(process.getWholeTime() / (double)process.getServiceTime()); } private void showExecuteMessage(int startTime, int endTime, String name) { System.out.println(startTime + "~" + endTime + ":【進程" + name + "】運行"); } public void showResult() { System.out.print("進程名\t"); System.out.print("周轉時間\t"); System.out.println("帶權周轉時間\t"); Process process ; while(!mExecutedQueue.isEmpty()) { process = mExecutedQueue.poll(); System.out.print("進程" + process.getName() + "\t"); System.out.print("\t" + process.getWholeTime() + "\t"); System.out.println("\t" + process.getWeightWholeTime() + "\t"); } System.out.println("平均周轉時間:" + mTotalWholeTime / (double) mProcessCount); System.out.println("平均帶權周轉時間:" + mTotalWeightWholeTime / (double) mProcessCount); } public static void printAll(Queue<Process> queue) { System.out.print("進程名\t"); System.out.print("到達時間\t"); System.out.println("服務時間\t"); Process process = null; while (!queue.isEmpty()){ process = queue.poll(); System.out.print("進程" + process.getName() + "\t"); System.out.print("\t" + process.getArrivalTime() + "\t"); System.out.println("\t" + process.getServiceTime() + "\t"); } } public static void main(String[] args) throws InterruptedException { Scanner scanner = new Scanner(System.in); System.out.println("輸入進程個數:"); int processCount = scanner.nextInt(); if(processCount < 1) return; Queue<Process> queue = new LinkedBlockingQueue<>(); System.out.println("依次輸入每個進程的到達時間(按到達順序):"); for(int i=0; i<processCount; i++) { Process process = new Process((char)(i + 65) + ""); process.setArrivalTime(scanner.nextInt()); queue.add(process); } System.out.println("依次輸入每個進程的服務時間(按到達順序):"); for(int i=0; i<processCount; i++) { Process process = queue.poll(); int time = scanner.nextInt(); process.setServiceTime(time); process.setRemainServiceTime(time); queue.add(process); } System.out.println("輸入時間片大小"); int timeSlice = scanner.nextInt(); RR rr = new RR(processCount, queue, timeSlice); System.err.println("*******************進程情況*****************"); Thread.sleep(1000); printAll(new LinkedBlockingQueue<>(queue)); Thread.sleep(1000); System.err.println("******************運行過程*****************"); Thread.sleep(1000); rr.RRAlgorithm(); Thread.sleep(1000); System.err.println("*******************運行結果*****************"); Thread.sleep(1000); rr.showResult(); } } //進程 class Process { private String name; private int arrivalTime; //到達時間 private int serviceTime; //服務時間 private int remainServiceTime; //還需要服務的時間 private int finishTime; //完成時間 private int wholeTime; //周轉時間 private double weightWholeTime; //帶權周轉時間 public int getRemainServiceTime() { return remainServiceTime; } public void setRemainServiceTime(int remainServiceTime) { this.remainServiceTime = remainServiceTime; } public Process(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getArrivalTime() { return arrivalTime; } public void setArrivalTime(int arrivalTime) { this.arrivalTime = arrivalTime; } public int getServiceTime() { return serviceTime; } public void setServiceTime(int serviceTime) { this.serviceTime = serviceTime; } public int getFinishTime() { return finishTime; } public void setFinishTime(int finishTime) { this.finishTime = finishTime; } public int getWholeTime() { return wholeTime; } public void setWholeTime(int wholeTime) { this.wholeTime = wholeTime; } public double getWeightWholeTime() { return weightWholeTime; } public void setWeightWholeTime(double weightWholeTime) { this.weightWholeTime = weightWholeTime; } }

運行結果當時間片為 1 時:

時間片為 4 時:

 

java學習群669823128


免責聲明!

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



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