最近在学习过程中了解到了关于CPU的调度算法,试着用Java简单模拟了多级反馈队列调度算法(学习阶段,可能存在bug)。
在CPU的多调度算法中,多级反馈队列算法是一种比较优秀的算法,其能够在快速响应高优先级的进程的同时兼顾到服务时间短的进程。该算法的原理就是:
①假设有多级队列,队列的优先级是从高到低的,处于优先级高的队列中的进程优先执行,每次有新的进程进入就将该进程放到第一级队列(优先级最高)的队尾;
②每一级队列都有相对应的时间片,其时间片长短与优先级相反是依次递增的,对于处于同一级队列的进程遵循先来先服务的算法,当该进程得到的时间片用完,如果该进程还未完成则将其放到下一级队列的队尾,如果该进程处于最后一级队列并且时间片用完还未完成则放到最后一级队列的队尾;
③处于高优先级队列的进程可以抢占正在执行的处于低优先级队列的进程,即每一时刻都是从处于高优先级队列的进程开始执行。
/*算法类*/
public class SchedulingAlgorithm {
/*java模拟CPU的多级反馈队列调度算法*/
public Process[] MFQ(Process[] process) {
int num = 0; //进程数组的下标
int currentTime = 0;//当前时间
int lastTime = -1; //上一时刻的时间
int firstTimeSlice = 2;//一级队列时间片
int secondTimeSlice = 4;//二级队列时间片
int thirdTimeSlice = 8;//三级队列时间片
int firstSlice = 0; //一级时间片计时器
int secondSlice = 0; //二级时间片计时器
int thirdSlice = 0; //三级时间片计时器
int currQueueId = -1; //执行进程所处的队列号
int k = 0; //返回新进程数组的下标
Process execProcess = null; //执行进程
Process[] newProcess = new Process[process.length]; //返回的新进程数组
LinkedList<Process> firstQueue = new LinkedList<>(); //一级队列
LinkedList<Process> secondQueue = new LinkedList<>(); //二级队列
LinkedList<Process> thirdQueue = new LinkedList<>(); //三级队列
while(num < process.length || firstQueue.size() != 0 ||
secondQueue.size() != 0 || thirdQueue.size() != 0) {//当各队列不为空或进程数组还有进程,循环继续
if((firstQueue.size() != 0 || secondQueue.size() != 0 || thirdQueue.size() != 0)) { //判断时间差,有时间差即进程执行,否则无执行
lastTime = currentTime - 1;
}else {
lastTime = currentTime;
}
while(num < process.length && process[num].getArriveTime() == currentTime) { //每一时刻判断是否有进程入队
firstQueue.offerLast(process[num]);
num++;
}
if(currQueueId == 1) { //当前执行的进程属于第一队列,使用第一队列的时间片
execProcess.setCompleteTime(execProcess.getCompleteTime()+currentTime-lastTime);//更新进程已执行时间
firstSlice += currentTime-lastTime; //更新时间片的计时器
if(execProcess.getServiceTime() == execProcess.getCompleteTime()) {//判断已执行时间是否等于服务时间,即进程完成
//更新进程的属性,初始化时间片等属性,将进程存入新进程数组
firstQueue.pollFirst();
execProcess.setEndTime(currentTime);
execProcess.setTotalTime(execProcess.getEndTime()-execProcess.getArriveTime());
newProcess[k++] = execProcess;
firstSlice = 0;
currQueueId = -1;
}else if(firstSlice == firstTimeSlice){//时间片用完,将该进程拿到下一等级队列的队尾,初始化各属性
firstSlice = 0;
currQueueId = -1;
firstQueue.pollFirst();
secondQueue.offerLast(execProcess);
}
}else if(currQueueId == 2) {//当前执行的进程属于第二队列,使用第二队列的时间片
execProcess.setCompleteTime(execProcess.getCompleteTime()+currentTime-lastTime);
secondSlice += currentTime-lastTime;
if(execProcess.getServiceTime() == execProcess.getCompleteTime()) {
secondQueue.pollFirst();
execProcess.setEndTime(currentTime);
execProcess.setTotalTime(execProcess.getEndTime()-execProcess.getArriveTime());
newProcess[k++] = execProcess;
secondSlice = 0;
currQueueId = -1;
}else if(secondSlice == secondTimeSlice){
secondSlice = 0;
currQueueId = -1;
secondQueue.pollFirst();
thirdQueue.offerLast(execProcess);
}
}else if(currQueueId == 3) {//当前执行的进程属于第三队列,使用第三队列的时间片
execProcess.setCompleteTime(execProcess.getCompleteTime()+currentTime-lastTime);
thirdSlice += currentTime-lastTime;
if(execProcess.getServiceTime() == execProcess.getCompleteTime()) {
thirdQueue.pollFirst();
execProcess.setEndTime(currentTime);
execProcess.setTotalTime(execProcess.getEndTime()-execProcess.getArriveTime());
newProcess[k++] = execProcess;
thirdSlice = 0;
currQueueId = -1;
}else if(thirdSlice == thirdTimeSlice){
thirdSlice = 0;
currQueueId = -1;
thirdQueue.pollFirst();
thirdQueue.offerLast(execProcess);
}
}
if(firstQueue.size()!=0) { //每一时刻都取出处于最高级别队列的队头进程
execProcess = firstQueue.peekFirst();
if(!execProcess.isExecute()) {//判断进程是否头次执行
execProcess.setStartTime(currentTime);
execProcess.setExecute(true);
}
currQueueId = 1;
}else if(secondQueue.size() != 0) {
execProcess = secondQueue.peekFirst();
currQueueId = 2;
}else if(thirdQueue.size() != 0) {
execProcess = thirdQueue.peekFirst();
currQueueId = 3;
}
System.out.println(currentTime);
System.out.println(firstQueue);
System.out.println(secondQueue);
System.out.println(thirdQueue);
currentTime++; //当前时间加一
}
return newProcess;
}
}
/*进程实体类*/
public class Process {
private int id;//进程号
private int arriveTime;//到达时间
private int serviceTime;//服务时间
private int startTime;//开始时间
private int endTime;//结束时间
private int totalTime;//周转时间
private int completeTime;//已完成部分的时间
private boolean execute = false;//是否头次执行
public Process() {}
public Process(int id, int arriveTime, int serviceTime) {
super();
this.id = id;
this.arriveTime = arriveTime;
this.serviceTime = serviceTime;
}
/* 省略get和set方法以及toString方法*/
}
/* 测试类 */
public class MainTest {
public static void main(String[] args) {
Process[] process = new Process[5];
Process p1 = new Process(1, 0, 3);
Process p2 = new Process(2, 4, 6);
Process p3 = new Process(3, 4, 4);
Process p4 = new Process(4, 6, 5);
Process p5 = new Process(5, 12, 2);
process[0] = p1;
process[1] = p2;
process[2] = p3;
process[3] = p4;
process[4] = p5;
SchedulingAlgorithm sa = new SchedulingAlgorithm();
Process[] newprocess = sa.MFQ(process);
for(Process p:newprocess) {
System.out.println(p);
}
}
}