时间片轮转(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;}}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 时:

【笔记】时间片轮转 RR 进程调度算法(Java 实现)相关推荐

  1. 操作系统时间片轮换_《操作系统_时间片轮转RR进程调度算法》

    转自:https://blog.csdn.net/houchaoqun_xmu/article/details/55540250 时间片轮转RR进程调度算法 一.概念介绍和案例解析 时间片轮转法 - ...

  2. 【操作系统 - 2】时间片轮转RR进程调度算法

    操作系统系列 2017.03.17:整理第一版. 2018.01.08:添加使用 DEV C++ 的说明. ======== 学习至此,发现很多学了但很久没用的知识,久而久之,慢慢遗忘.等哪天还需要的 ...

  3. 时间片轮转RR进程调度算法(操作系统实验 C+)

    时间片轮转RR进程调度算法 1.实验目的 通过这次实验,加深对进程概念的理解,进一步掌握进程状态的转变.进程调度的策略及对系统性能的评价方法. 2.实验内容 问题描述: 设计程序模拟进程的时间片轮转R ...

  4. 操作系统:时间片轮转RR进程调度算法

    目的:陆续整理近一年的学习收获 时间片轮转RR进程调度算法 一:概念 时间片轮转RR进程调度算法:用于分时系统中的进程调度.每次调度时,总是选择就绪队列的队首进程,让其在CPU上运行一个系统预先设置好 ...

  5. 操作系统实验之时间片轮转RR进程调度算法

    一.实验内容 设计程序模拟进程的时间片轮转RR调度过程.假设有n个进程分别在T1, - ,Tn时刻到达系统,它们需要的服务时间分别为S1, - ,Sn.分别利用不同的时间片大小q,采用时间片轮转RR进 ...

  6. 实验名称:时间片轮转RR进程调度算法

    实验目的 通过这次实验,加深对进程概念的理解,进一步掌握进程状态的转变.进程调度的策略及对系统性能的评价方法. 实验内容 问题描述: 设计程序模拟进程的时间片轮转RR调度过程.假设有n个进程分别在T1 ...

  7. 《操作系统》实验三:高响应比优先调度和时间片轮转RR进程调度算法

    [实验题目]:高响应比优先调度和时间片轮转RR进程调度算法 [实验学时]:4学时 [实验目的] 通过这次实验,加深对进程调度概念的理解,进一步掌握比FCFS和SJF更为复杂的进程调度算法的实现方法. ...

  8. c++时间片轮转rr进程调度算法_「学习笔记」时间片轮转(RR)调度算法(详解版)...

    关键词:时间, 进程, 调度, 队列, 切换 时间片轮转(RR)时间片轮转(RR)调度算法是专门为分时系统设计的.它类似于 FCFS调度,但是增加了抢占以切换进程. 该算法中,将一个较小时间单... ...

  9. c++时间片轮转rr进程调度算法_进程,线程基础(—)

    进程 进程简单的定义是指装载到内存的指令集并且正在由cpu执行其中的每一条指令的这个程序叫做进程. 进程控制块 process control block 简称PCB,主要包含了标识符,状态,优先级, ...

  10. java 时间片_Java 实现--时间片轮转 RR 进程调度算法

    时间片轮转(Round-Robin)调度算法是操作系统一种比较公平的进程调度的方式,这种方式使得就绪队列上的所有进程在每次轮转时都可以运行相同的一个时间片. 基本原理 算法实现原理是,按进程到达顺序( ...

最新文章

  1. pyvmomi 实现VMware自动化
  2. R语言tidyr包spread()函数实战详解:数据裂变、从窄表到宽表
  3. python3 post 文件 消息
  4. hdu 5172(RMQ+前缀和)
  5. C++之explicit关键字使用总结
  6. 进程同步与互斥的区别
  7. MySQL源码解读之数据结构-LF_DYNARRAY
  8. 打印机的共享设置方法
  9. springboot pom文件基本配置
  10. static和const关键字
  11. 2019,跟着大佬追逐技术前沿
  12. python熊猫烧香_熊猫烧香的核心代码
  13. 分布式系统的基本特征
  14. 计算机学院部长换届答辩,未来可期,各自精彩——记计算机科学学院2020年两委换届竞职答辩活动...
  15. 动态规划求解金矿问题
  16. c语言指针实现数组排序算法,C语言实现数组快速排序算法
  17. c语言小蜜蜂编程题,小蜜蜂 pascal程序
  18. ubuntu系统中webpy的使用
  19. Java=微信支付详解与日志记录详解
  20. AT2402E射频前端单芯片替代RFX2402E

热门文章

  1. Java 操作 EXCEL
  2. iOS ASI--文件下载
  3. Can't add self as subview crash错误
  4. 图片文字混排的垂直居中、inline-block块元素和行内元素混排的垂直居中问题
  5. 发点牢骚,关于微软,关于WPF/E
  6. 在idea或eclipse软件下配置Tomcat
  7. java读取资源文件(Properties)
  8. Git版本控制的原理
  9. python学习-- Django根据现有数据库,自动生成models模型文件
  10. ZeroMQZeroMQ研究与应用分析