0、资源下载链接:csdn资源下载
一、 设计要求
编写并调试一个模拟的进程调度程序,采用采用分别先来先服务(FCFS),以及最短进程优先(SPF)、响应比高者优先(HRN)的调度算法进行调度。
二、 运行环境
此程序运行于Java 16.0.2 环境中,在windows系统
三、 系统功能
模拟多进程的调度,本程序采用了可选择先来先服务算法、最短进程优先算法和响应比高者算法进行调度。
用户使用模拟功能前先输入自定义的进程信息包括:序号、进程名、优先级、服务时间和到达时间。然后通过选择框选择需要使用的调度算法进行执行模拟,将会得到以上信息以及开始运行时间、结束运行时间、周转时间和带权周转时间的表格信息,以及总平均周转时间和平均带权周转时间。
用户在执行后也可以进行撤销执行,方便用户体验其他算法,避免重复输入进程信息的繁琐。
四、 所用的数据结构
public class PCB {
public int id; //序号
public String name; //进程名
public int priority; //优先级
public double workTime; //服务时间
public double arriveTime; //到达时间
public double beginTime; //开始运行时间
public double finshTime; //运行结束时间
public double TAT; //周转时间
public double WTAT; //带权周转时间
}
五、 主要函数功能
- 先来先服务算法(FCFS)
public class FCFS {
public static ArrayList<PCB> FCFS(ArrayList<PCB> PCBArr) {
//根据到达时间将输入队列排序,同时到达的进程根据序号排序
for(int i=0;i<PCBArr.size();i++) {
for(int j=i+1;j<PCBArr.size();j++) {
if(PCBArr.get(i).getArriveTime()>PCBArr.get(j).getArriveTime()) {
Collections.swap(PCBArr, i, j);
}
}
}
//复制原PCB数组
ArrayList<PCB> tempArr = PCBArr;
//存储结果数组
ArrayList<PCB> workArr = new ArrayList<PCB>();
for(PCB p : tempArr) {
if(workArr.size() == 0){ //执行第一个进程
p.setBeginTime(p.getArriveTime());
p.setFinshTime(p.getBeginTime()+p.getWorkTime());
} else {
p.setBeginTime(workArr.get(workArr.size()-1).getFinshTime());
p.setFinshTime(p.getBeginTime()+p.getWorkTime());
}
workArr.add(p);
}
return workArr;
}
}
- 最短进程优先算法(SPF)
public class SPF {
public static ArrayList<PCB> SPF(ArrayList<PCB> PCBArr) {
//根据到达时间获取第一个到达并且服务时间较短的进程
PCB first;
first = PCBArr.get(0);
for(int i=0;i<PCBArr.size();i++) {
if(first.getArriveTime() == PCBArr.get(i).getArriveTime()) {
if(first.getWorkTime() > PCBArr.get(i).getWorkTime()) {
first = PCBArr.get(i);
}
} else if(first.getArriveTime() > PCBArr.get(i).getArriveTime()) {
first = PCBArr.get(i);
}
}
//复制原PCB数组
ArrayList<PCB> tempArr = new ArrayList<PCB>();
for (int i=0;i<PCBArr.size();i++) {
tempArr.add(PCBArr.get(i));
}
//第一个进入工作队列中
ArrayList<PCB> workArr = new ArrayList<PCB>(); //存储结果数组
workArr.add(first);
workArr.get(0).setBeginTime(first.getArriveTime());
workArr.get(0).setFinshTime(first.getArriveTime()+first.getWorkTime());
//删除已经进入工作队列的第一个进程的PCB
tempArr.remove(first);
//剩下的进程通过最短进程优先调度算法依次进入工作队列
while(!tempArr.isEmpty()) {
ArrayList<PCB> temp = new ArrayList<PCB>();
double lastFinshTime = workArr.get(workArr.size()-1).getFinshTime();
//筛选出在上一个进程结束前到达的进程放入temp数组
for(PCB p : tempArr) {
if(p.getArriveTime() < lastFinshTime) {
temp.add(p);
}
}
if(temp.isEmpty()){
for(PCB p : tempArr)
temp.add(p);
}
//筛选出temp数组中最短的进程first2
PCB first2;
first2 = temp.get(0);
for(int i=0;i<temp.size();i++) {
if(first2.getWorkTime() > temp.get(i).getWorkTime())
first2 = temp.get(i);
}
//将first2对应进程放入工作队列并运行,同时在临时复制的PCB(tempArr)中删除该进程的PCB
first2.setBeginTime(lastFinshTime);
first2.setFinshTime(first2.getBeginTime()+first2.getWorkTime());
workArr.add(first2);
tempArr.remove(first2);
}
return workArr;
}
}
- 响应比高者优先算法(HRN)
public class HRN {
//响应比 =(等待时间 + 工作时间)/ 工作时间
public static ArrayList<PCB> HRN(ArrayList<PCB> PCBArr) {
//由于刚开始多个进程如果同时第一个到达,其响应比都为1,所以不做判断,只根据到达时间获取第一个到达的进程
PCB first;
first = PCBArr.get(0);
for(int i=0;i<PCBArr.size();i++) {
if(first.getArriveTime() > PCBArr.get(i).getArriveTime()) {
first = PCBArr.get(i);
}
}
//复制原PCB数组
ArrayList<PCB> tempArr = new ArrayList<PCB>();
for (int i=0;i<PCBArr.size();i++) {
tempArr.add(PCBArr.get(i));
}
//第一个进入工作队列中
ArrayList<PCB> workArr = new ArrayList<PCB>(); //存储结果数组
workArr.add(first);
workArr.get(0).setBeginTime(first.getArriveTime());
workArr.get(0).setFinshTime(first.getArriveTime()+first.getWorkTime());
//删除已经进入工作队列的第一个进程的PCB
tempArr.remove(first);
//剩下的进程通过响应比高者优先调度算法依次进入工作队列
while(!tempArr.isEmpty()) {
ArrayList<PCB> temp = new ArrayList<PCB>();
double lastFinshTime = workArr.get(workArr.size()-1).getFinshTime();
//筛选出在上一个进程结束前到达的进程放入temp数组
for(PCB p : tempArr) {
if(p.getArriveTime() < lastFinshTime) {
temp.add(p);
}
}
if(temp.isEmpty()){
for(PCB p : tempArr)
temp.add(p);
}
//筛选出temp数组中响应比最高的进程first2
PCB first2;
first2 = temp.get(0);
//记录当前first2指定进程的响应比
double largeHrn = ((workArr.get(workArr.size()-1).getFinshTime()-first2.getArriveTime()) + first2.getWorkTime()) / first2.getWorkTime();
for(int i=0;i<temp.size();i++) {
double hrn = ((workArr.get(workArr.size()-1).getFinshTime()-temp.get(i).getArriveTime()) + temp.get(i).getWorkTime()) / temp.get(i).getWorkTime();
if(largeHrn < hrn) {
largeHrn = hrn;
first2 = temp.get(i);
}
}
//将first2对应进程放入工作队列并运行,同时在临时复制的PCB(tempArr)中删除该进程的PCB
first2.setBeginTime(lastFinshTime);
first2.setFinshTime(first2.getBeginTime()+first2.getWorkTime());
workArr.add(first2);
tempArr.remove(first2);
}
return workArr;
}
}
- 图形化相关代码
由于代码过长将不放在报告内影响报告篇幅
六、 运行情况
-
测试用例(序号、进程名、优先级、服务时间、到达时间)
new PCB(1, “P1”, 3, 10, 1);
new PCB(2, “P2”, 1, 3, 1);
new PCB(3, “P3”, 5, 2, 3);
new PCB(4, “P4”, 4, 1, 3);
new PCB(5, “P5”, 2, 5, 3);
到达时间有相同且有存在后备队列等待能很好测试各个调度算法
-
先来先服务调度算法
-
最短进程优先调度算法
-
高响应比者调度算法