实验报告4-进程调度
一、实现思路
1、关于进程调度
无论是在批处理系统还是分时系统中,用户进程数一般都多于处理机数、这将导致它们互相争夺处理机。另外,系统进程也同样需要使用处理机。这就要求进程调度程序按一定的策略,动态地把处理机分配给处于就绪队列中的某一个进程,以使之执行。
2、衡量指标
衡量进程调度性能的指标有:平均周转时间、平均加权周转时间、平均等待时间等。
3、先来先服务调度算法
按照作业/进程到达的先后顺序进行调度,即:优先考虑在系统中等待时间最长的作业。一个进程一旦占有了处理机,它就一直运行下去,直到该进程完成其工作或因等待某事件而不能继续运行时才释放处理机。FIFO算法为非抢占方式。
二、实验步骤
1、Process类
public class Process {
private String no;//编号
private double arriveTime;// 到达时间
private double serverTime;// 运行时间
private double startTime;// 开始时间
public String getNo() {
return no;
}
public void setNo(String no) {
this.no = no;
}
public Double getArriveTime() {
return arriveTime;
}
public void setArriveTime(double arriveTime) {
this.arriveTime = arriveTime;
}
public Double getServerTime() {
return serverTime;
}
public void setServerTime(double serverTime) {
this.serverTime = serverTime;
}
public Double getStartTime() {
return startTime;
}
public void setStartTime(double startTime) {
this.startTime = startTime;
}
// 结束时间
public double getEndTime() {
return startTime + serverTime;
}
// 周转时间=结束时间-到达时间
public double getTi() {
return getEndTime()-arriveTime;
}
// 加权周转时间=周转时间/运行时间
public double getWi() {
return getTi()/serverTime;
}
// 等待时间=开始时间-到达时间
public double getWt() {
return startTime - arriveTime;
}
}
2、ProcessSchedule类
public class ProcessSchedule {
//作业序列
private List<Process> list = new ArrayList<>();
//构造函数,初始化作业序列
public ProcessSchedule(String[] processNos,double processArgs[][]) {
for (int i = 0; i < processArgs.length; i++) {
Process process = new Process();
process.setNo(processNos[i]);
process.setArriveTime(processArgs[i][0]);
process.setServerTime(processArgs[i][1]);
list.add(process);
}
}
//先来先服务调度算法
public void FCFS(){
//作业序列按到达时间排序
list.sort(new Comparator<Process>() {
@Override
public int compare(Process o1, Process o2) {
if (o1.getArriveTime()<o2.getArriveTime()){
return -1;
}
else if(o1.getArriveTime()>o2.getArriveTime()){
return 1;
}else {
return 0;
}
}
});
//设置第一个到达进程的开始时间,即该进程的到达时间
list.get(0).setStartTime(list.get(0).getArriveTime());
//获取第一个进程的结束时间
Double endTime = list.get(0).getEndTime();
//遍历其它进程
for (int i = 1; i < list.size(); i++) {
//如果当前进程的到达时间小于上一个进程的结束时间
if (list.get(i).getArriveTime()<endTime){
//当前进程的开始时间等于上一个进程的结束时间
list.get(i).setStartTime(endTime);
}
//否则
else {
//当前进程的开始时间等于该进程的到达时间
list.get(i).setStartTime(list.get(i).getArriveTime());
}
//获取当前进程的结束时间
endTime=list.get(i).getEndTime();
}
System.out.println("FCFS先来先服务进程调度算法运行结果:");
//格式化输出
show();
//计算平均周转时间、平均加权周转时间、平均等待时间
double avgTi = 0;
double avgWi = 0;
double avgWt = 0;
for (Process p:list) {
avgTi += p.getTi();
avgWi += p.getWi();
avgWt += p.getWt();
}
avgTi /= list.size();
avgWi /= list.size();
avgWt /= list.size();
System.out.println(String.format("平均周转时间为:%.2f",avgTi));
System.out.println(String.format("平均加权周转时间为:%.2f",avgWi));
System.out.println(String.format("平均等待时间为:%.2f",avgWt));
}
//格式化输出
private void show() {
System.out.println("作业编号\t到达时间\t运行时间\t开始时间\t结束时间\t周转时间\t加权周转时间\t等待时间");
for (Process process:list) {
System.out.print(process.getNo() + "\t\t");
System.out.print(String.format("%.2f", process.getArriveTime()) + "\t");
System.out.print(String.format("%.2f", process.getServerTime()) + "\t");
System.out.print(String.format("%.2f", process.getStartTime()) + "\t");
System.out.print(String.format("%.2f", process.getEt()) + "\t");
System.out.print(String.format("%.2f", process.getTi()) + "\t");
System.out.print(String.format("%.2f", process.getWi()) + "\t\t");
System.out.print(String.format("%.2f", process.getWt()) + "\n");
}
}
}
3、Test类
public class Test {
public static void main(String[] args) {
//作业编号
String[] processNos = {"1","2","3","4","5"};
//到达时间、运行时间
double[][] processArgs = {
{8.0, 1.0},
{9.0, 0.5},
{8.5, 0.5},
{9.0, 0.2},
{9.1, 0.1}
};
//初始化
ProcessSchedule schedule = new ProcessSchedule(processIds,processArgs);
//执行先来先服务调度算法
schedule.FCFS();
}
}