轮转调度算法
在分时系统中,最简单也是较常用的是基于时间片的轮转(round robin,RR)调度算法。该算法采用非常公平的处理机分配方式,即让就绪队列上的每个进程每次仅运行一个时间片。如果就绪队列上有n个进程,则每个进程每次大约都可以获得1/n的处理机时间。
-
轮转法是基本原理
在轮转(RR)法中,系统根据FCFS策略,将所有的就绪进程排成一个就绪队列,并可设置每隔一定时间间隔(如30ms)产生一个中断,激活系统中的进程调度程序,完成一次调度,将CPU分配给队首进程,另其执行。当该进程的时间片耗尽或运行完毕时,系统再次将CPU分配给队首进程(或新到达的紧迫进程)。由此,可保证就绪队列中的所有进程在一个确定的时间段内,都能够获得一次CPU执行。
以下是算法:
进程类Process
package com.RouletteSchedulingAlgorithm;
/**
* 进程类Process
* @ClassName: Process
*/
public class Process {
private int arriveTime;//到达时间
private int serverTime;//服务时间,可以修改
private int finishTime;//完成时间
private int turnoverTime;//周转时间
private double quanTurnoverTime;//带权周转时间
public int getRealServerTime() {
return realServerTime;
}
public void setRealServerTime(int realServerTime) {
this.realServerTime = realServerTime;
}
private int realServerTime; //真正的服务时间,不能修改
public Process() {
}
public Process(int arriveTime, int serverTime) {
super();
this.arriveTime = arriveTime;
this.serverTime = serverTime;
}
public int getArriveTime() {
return arriveTime;
}
public void setArriveTime(int arriveTime) {
this.arriveTime = arriveTime;
}
public int getServerTime() {
return serverTime;
}
public void setServerTime(int serverTime) {
this.serverTime = serverTime;
}
public int getFinishTime() {
return finishTime;
}
public void setFinishTime(int finishTime) {
this.finishTime = finishTime;
}
public int getTurnoverTime() {
return turnoverTime;
}
public void setTurnoverTime(int turnoverTime) {
this.turnoverTime = turnoverTime;
}
public double getQuanTurnoverTime() {
return quanTurnoverTime;
}
public void setQuanTurnoverTime(double quanTurnoverTime) {
this.quanTurnoverTime = quanTurnoverTime;
}
}
具体实现类RouletteSchedule
package com.RouletteSchedulingAlgorithm;
import java.text.DecimalFormat;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
/**
* 轮转调度算法
*
* @ClassName: RouletteSchedule
*/
public class RouletteSchedule {
private static int finishTime = 0;
public static void main(String[] args) {
System.out.println("请输入时间片段RR,一个整数值");
@SuppressWarnings("resource")
Scanner s = new Scanner(System.in);
int q = s.nextInt(); // 时间片段RR
Process A = new Process(0,4);
Process B = new Process(1,3);
Process C = new Process(2,4);
Process D = new Process(3,2);
Process E = new Process(4,4);
//传到真正的服务时间
A.setRealServerTime(A.getServerTime());
B.setRealServerTime(B.getServerTime());
C.setRealServerTime(C.getServerTime());
D.setRealServerTime(D.getServerTime());
E.setRealServerTime(E.getServerTime());
List<Process> list = new LinkedList<Process>();
list.add(A);
list.add(B);
list.add(C);
list.add(D);
list.add(E);
//获取并移除队列的头
Process p;
while((p = (Process)((LinkedList<Process>) list).poll()) !=null ) {
//进程服务的时间 小于等于 时间片段p
if(p.getServerTime() <= q) {
p.setFinishTime(finishTime + p.getServerTime());
finishTime += p.getServerTime();
p.setTurnoverTime(p.getFinishTime() - p.getArriveTime());
p.setQuanTurnoverTime((double) p.getTurnoverTime() / (double)p.getRealServerTime());
}else if(p.getServerTime() > q){ //大于
p.setFinishTime(finishTime + q);
finishTime += q;
p.setServerTime(p.getServerTime() - q);
list.add(p);//将进程移植队尾
}
}
print(A);
print(B);
print(C);
print(D);
print(E);
//打印平均周转时间
avgTurnoverTime(A,B,C,D,E);
//打印带权周转时间
avgQuanTurnoverTime(A,B,C,D,E);
}
/**
* 打印输出结果
* @Title: print
* @return void
*/
//格式化小数,保留两位小数
static DecimalFormat df = new DecimalFormat("0.00");
private static int i = 1;
public static void print(Process p) {
System.out.println("第"+(i++)+"个进程 完成时间: "+p.getFinishTime()+"\t周转时间: "+
p.getTurnoverTime()+"\t带权周转时间:"+df.format(p.getQuanTurnoverTime()));
}
/**
* 平均周转时间
*/
public static void avgTurnoverTime(Process...process) {
int i = 0;
double sum = 0;
for (Process p : process) {
sum += p.getTurnoverTime();
i++;
}
System.out.println("平均周转时间为:"+sum/i);
}
/**
* 平均带权周转时间
*/
public static void avgQuanTurnoverTime(Process...process) {
int i = 0;
double sum = 0;
for (Process p : process) {
sum += p.getQuanTurnoverTime();
i++;
}
System.out.println("平均带权周转时间为:"+df.format(sum/i));
}
}