时间片轮转算法实现
一、实验内容
编程实现时间片轮转算法,并求出每个作业的完成时间、周转时间、带权周转时间,及平均周转时间、平均带权周转时间。
二、实验要求
- 任选一种高级语言实现;
- 选择1-2种调度算法;
- 能够输入进程的基本信息,如进程名、提交时间、预估运行时间等;
- 根据选择的调度算法显示进程调度顺序;
- 显示完成调度后每个进程的开始时间、完成时间呢、周转时间,带权周转时间;
- 计算平均周转时间和平均带权周转时间;
三、实验过程
1、 设计思想
系统将所有的就绪进程按FCFS策略排成一个就绪队列。系统可设置每隔一定时间(如30ms)便产生一次中断,去激活进程调度程序进行调度,把CPU分配给队首进程,并令其执行一个时间片。当它运行完毕后,将进程管道就绪队列的队尾,再把处理机分配给就绪队列中新的队首进程,也让它执行一个时间片,以此类推。这样,就可以保证就绪队列中的所有进程在确定的时间段内,都能获得一个时间片的处理机时间。
将进程按FCFS排成一个队列,每次调度取队首进程分配CPU,时间片到,将PCB挂到就绪队尾。
在时间片轮转调度算法中,应在何时进行进程的切换,可分为两种情况:
① 若一个时间片尚未用完,正在运行的进程便已经完成,就立即激活调度程序,将它从就绪队列中删除,再调度就绪队列中队首的进程运行,并启动一个新的时间片。
② 在一个时间片用完时,计时器中断处理程序被激活。如果进程尚未运行完毕,调度程序将把它送往就绪队列的末尾。
2.运行结果
四、实验代码
public class Thread {
int id;//进程ID
int arrivetime;//到达时间
int runtime;//运行时间
int rmaintime;//剩余运行时间
int endtime;//完成时间
int turnovertime;//周转时间
float qturnovertime;//带权周转时间
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getArrivetime() {
return arrivetime;
}
public void setArrivetime(int arrivetime) {
this.arrivetime = arrivetime;
}
public int getRuntime() {
return runtime;
}
public void setRuntime(int runtime) {
this.runtime = runtime;
}
public int getRmaintime() {
return rmaintime;
}
public void setRmaintime(int rmaintime) {
this.rmaintime = rmaintime;
}
public int getEndtime() {
return endtime;
}
public void setEndtime(int endtime) {
this.endtime = endtime;
}
public int getTurnovertime() {
return turnovertime;
}
public void setTurnovertime(int turnovertime) {
this.turnovertime = turnovertime;
}
public float getQturnovertime() {
return qturnovertime;
}
public void setQturnovertime(float qturnovertime) {
this.qturnovertime = qturnovertime;
}
public Thread() {
id=0;
arrivetime=0;//到达时间
runtime=0;//运行时间
rmaintime=0;//剩余运行时间
endtime=0;//完成时间
turnovertime=0;//周转时间
qturnovertime=0;//带权周转时间
}
public Thread(int id, int arrivetime, int runtime,int rmaintime) {
this.id = id;
this.arrivetime = arrivetime;
this.runtime = runtime;
this.rmaintime=rmaintime;
}
@Override
public String toString() {
return "Thread{" +
"id=" + id +
", arrivetime=" + arrivetime +
", runtime=" + runtime +
", rmaintime=" + rmaintime +
'}';
}
}
package com.hu;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Random;
public class Test {
static final int slicetime=2;//时间片大小设为2
public static void main(String[] args) {
RR(InitQueue(SortThread(InitThread())));
}
public static void RR(LinkedList queue){
int i=0;
int count=0;
for (Iterator iter = queue.iterator(); iter.hasNext();){
System.out.println();
Thread thread =(Thread) queue.getFirst();
System.out.println(thread);
if (thread.rmaintime<=slicetime){
count=count+thread.rmaintime;//当前时间
thread.endtime=count;//结束时间
thread.turnovertime= thread.endtime-thread.arrivetime;//周转时间
thread.qturnovertime=(float)thread.turnovertime/thread.runtime;//带权周转时间
thread.rmaintime=0;
System.out.println(thread.getId()+"号进程结束"+"结束时间:"+thread.endtime+"周转时间:"+thread.turnovertime+"带权周转时间:"+thread.qturnovertime);
queue.remove();
}else {
count=count+2;//当前时间
thread.rmaintime=thread.rmaintime-slicetime;//执行进程
queue.remove();
queue.offer(thread);//时间片完插入队尾
}
}
}
public static Thread[] InitThread(){//初始化进程到达时间与运行时间
Thread[] thread = new Thread[5];
for (int i=0;i<thread.length;i++){
Random random = new Random();
int t= random.nextInt(10)+1;
thread[i] = new Thread(i,random.nextInt(10)+1,t,t);
}
return thread;
}
public static Thread[] SortThread(Thread[] threads) {//进程排序
for (int i = 0; i < threads.length; i++) {
for (int j = 0; j < threads.length - 1; j++) {
if (threads[j].arrivetime > threads[j + 1].arrivetime) {//如果进程到达时间不相等按进程的到达时间从小到大排序
Thread t;
t = threads[j];
threads[j] = threads[j + 1];
threads[j + 1] = t;
}
if (threads[j].arrivetime == threads[j + 1].arrivetime) {//如果进程到达时间相等按进程的运行时间从小到大排序
if (threads[j].runtime > threads[j + 1].runtime) {
Thread t;
t = threads[j];
threads[j] = threads[j + 1];
threads[j + 1] = t;
}
}
}
}
return threads;
}
public static LinkedList InitQueue(Thread[] threads){//初始化队列
LinkedList<Thread> queue = new LinkedList<Thread>();
for (int i=0;i< threads.length;i++){
queue.offer(threads[i]);
}
return queue;
}
}