实验三 进程模拟调度实验
一、实验目的
多道系统中,当就绪进程数大于处理机数时,须按照某种策略决定哪些进程优先占用处理机,本实验模拟实现处理机调度,以加深了解处理机调度的工作
二、实验内容
选择一个调度算法,实现处理机调度。
三、实验要求
1、设计一个按下面三种调度算法实现处理机调度的程序。
1)先来先服务
2)短进程优先或优先权高优先
3)按时间片轮转
2、说明:PCB内容: 进程名/PID 、要求运行时间(单位时间)、优先权、状态 、到达时间、已用CPU时间等。
1) 可随机输入若干进程,并按优先权排序。
2) 从就绪选进程运行,优先权-1,要求运行时间=0时,撤消该进程。
3)每次调度后,显示各进程状态 。重新排序进行下轮调度。
本实验模是拟实现处理机调度,添加时要求写明该进程属性:进程名,运行时间,优先权等,然后按优先权排序,将具有最高优先权的进程的状态设为:运行,其他为:就绪,若优先权相同,则以其他原则决定,如:要求运行时间短的优先。
时间片轮转调度算法中,设定一个时间段T,在该时间段内,若该进程没运行完(即t>T),则中止该进程,优先权降一级,重新排序,修改状态。若在该时间段内运行完毕(即t<T),则当要求运行时间=0时,撤消该进程,然后重新排序,修改状态。所以,该界面应该每过一段时间更改一次,至于“要求时间”的修改可每过1秒修改一次。
程序主界面:
图3-1 进程模拟调度流程图
四、实验报告
1、 可随机增加进程。
2、程序中使用的数据结构及符号说明。
3、一份源程序并附上注释。
4、要求附上程序模拟运行时的初值和运行结果。
1.代码部分(代码中有注释,就不另外说明):
三个类:
一个主类调用
一个process类
包含进程参数和调用方法
一个打印
打印主菜单和执行菜单
public class Main {
public static void main(String[] args) {
// 进入系统
int command=0;
Scanner in=new Scanner(System.in);
ArrayList<process> processes=new ArrayList<>();
while (command!=4){
PrintSth.menu();
command=in.nextInt();
if (command==1){
System.out.println("请输入随机创建的进程的个数:");
int temp=in.nextInt();
processes= process.CreateProcesses(temp,processes);
}
else if (command==2){
process.readProcess(processes);
}
else if(command==3){
process.CancelProcess(processes);
}
else if(command==4){
process.run(processes);
}
else if(command==5){
return;
}
else {
System.out.println("输入有误,重新输入!");
}
}
}
}
//直接在这个包内创建这个类,避免弄混,以及简化一些代码
public class process {
int id;//进程id
String name;//进程名称
int priority;//优先级最高为5,最低为1
int size;//所占内存大小
int time;//服务时间
int arriveTime;//到达时间
int exeTime;//执行时间
int beginTime;//开始时间
int finshTime;//完成时间
int roundTime;//周转时间
double aveRoundTime;//带权周转时间
process(int id, String name, int priority, int size, int time, int arriveTime) {
this.id = id;
this.name = name;
this.priority = priority;
this.size = size;
this.time = time;
this.arriveTime = arriveTime;
exeTime = 0;
}
public static ArrayList<process> CreateProcesses(int num, ArrayList<process> processes) {
int id;
String name;
int priority = 5;
int PCB;
int time;
int arriveTime;
if (num > 0) {
for (int i = 0; i < num; i++) {
id = i + 1;
name = "进程" + id;
priority = (int) (5 * Math.random());
if (priority == 0) {
while (priority == 0)
priority = (int) (5 * Math.random());
}
PCB = (int) (30 * Math.random());
time = (int) (20 * Math.random());
arriveTime = i;
process process = new process(id, name, priority, PCB, time, arriveTime);
processes.add(process);
}
} else {
System.out.println("输入有误!请重新输入!");
}
return processes;
}
public static void readProcess(ArrayList<process> processes) {
System.out.println("进程id 进程名 进程优先级 进程到达时间 进程运行时间 进程内存");
for (int i = 0; i < processes.size(); i++) {
System.out.println(
processes.get(i).id +
" " + processes.get(i).name
+ " " + processes.get(i).priority
+ " " + processes.get(i).arriveTime
+ " " + processes.get(i).time
+ " " + processes.get(i).size);
}
}
public static void CancelProcess(ArrayList<process> processes) {
System.out.println("请输入要取消的进程的id:");
Scanner in = new Scanner(System.in);
int temp = in.nextInt();
processes.remove(temp - 1);
}
public static void run(ArrayList<process> processes) {
// 为简化问题,这里的进程到达时间令它为与id相同时间
PrintSth.excutionmenu();
Scanner in = new Scanner(System.in);
int c = in.nextInt();
while (c!= 5) {
if (c == 1) {
FCFS(processes);
} else if (c == 2) {
SJF(processes);
} else if (c == 3) {
System.out.println("请输入时间片大小:");
int q =in.nextInt();
RR(processes,q);
} else if (c == 4) {
HRN(processes);
} else if (c == 5) {
return;
} else System.out.println("输入错误,请重新输入!");
PrintSth.excutionmenu();
c = in.nextInt();
}
}
public static void FCFS(ArrayList<process> processes) {
System.out.println("先来先服务算法:");
Queue<process> endQueue = new LinkedList<>();
Queue<process> readyQueue = new LinkedList< >();
int time = 0;
int size;
double total = 0;
System.out.println(time + "s:");
while (endQueue.size() < processes.size()) {
// 是否有队列到达
for (int i = 0; i < processes.size(); i++) {
// 控制进程到达准备队列
if (processes.get(i).arriveTime == time) {
readyQueue.add(processes.get(i));
processes.get(i).beginTime = time;
System.out.println("进程" + i + "到达");
}
}
// 进程执行
process process = readyQueue.peek();
System.out.println("进程" + process.id + "执行");
if (process.exeTime == process.time) {
process = readyQueue.poll();
endQueue.offer(process);
process.roundTime = time - process.arriveTime;
process.finshTime = time;
process.aveRoundTime = (process.roundTime + 0.0) / process.exeTime;
System.out.println("进程" + process.id + "执行完成");
}
time++;
process.exeTime++;
System.out.println(time + "s:");
//执行结束
if (readyQueue.isEmpty()) {
size = endQueue.size();
for (process p : endQueue) {
total = total + p.aveRoundTime;
System.out.println("进程:" + p.id + "\t完成时间:\t" + p.finshTime
+ "\t周转时间:\t" + p.roundTime + "带权周转时间:\t" + p.aveRoundTime + "\n");
}
System.out.println("平均带权周转时间:\t" + (total / size));
}
}
}
public static void RR(ArrayList<process> processes,int q) {
Queue<process> endQueue = new LinkedList<>();
Queue<process> readyQueue = new LinkedList<>();
boolean flag=false;
int time = 0;
int size;
double total = 0;
System.out.println(time + "s:");
while(endQueue.size()<processes.size()){
// 是否有队列到达
// 按时间片执行
for (int i = 0; i < q; i++) {
for (int j = 0; j < processes.size(); j++) {
// 控制进程到达准备队列
if (processes.get(j).arriveTime == time) {
readyQueue.add(processes.get(j));
processes.get(j).beginTime = time;
System.out.println("进程" + j + "到达");
}
}
process process = readyQueue.peek();
System.out.println("进程" + process.id + "执行");
time++;
process.exeTime++;
//进程完成
if (process.exeTime == process.time) {
process = readyQueue.poll();
endQueue.offer(process);
process.roundTime = time - process.arriveTime;
process.finshTime = time;
process.aveRoundTime = (process.roundTime + 0.0) / process.exeTime;
System.out.println("进程" + process.id + "执行完成");
break;
}
process pro = null;
if (i == q - 1 && !flag && !readyQueue.isEmpty()) {
pro = readyQueue.poll();
System.out.println(" 进程" + pro.id + "在该时间片内未完成, 中断执行");
}
System.out.println(time + "s: ");
if (pro != null) {
readyQueue.offer(pro);
}
}
if (readyQueue.isEmpty()) {
size = endQueue.size();
for (process p : endQueue) {
total = total + p.aveRoundTime;
System.out.println("进程:" + p.id + "\t完成时间:\t" + p.finshTime
+ "\t周转时间:\t" + p.roundTime + "带权周转时间:\t" + p.aveRoundTime + "\n");
}
System.out.println("平均带权周转时间:\t" + (total / size));
}
}
}
public static void HRN(ArrayList<process> processes) {
Queue<process> endQueue = new LinkedList<>();
ArrayList<process> readyList = new ArrayList<>();
int time = 0;
int size;
double total = 0;
boolean flag = false;
process process = null;
System.out.println(time + "s:");
while (endQueue.size() < processes.size()) {
// 是否有队列到达
for (int i = 0; i < processes.size(); i++) {
// 控制进程到达准备队列
if (processes.get(i).arriveTime == time) {
processes.get(i).beginTime = time;
System.out.println("进程" + (i+1) + "到达");
readyList.add(processes.get(i));
//使用冒泡排序,将进入数组中的进程按优先级排序
Sort.HRNSort(readyList,time);
}
}
// 进程执行
if (!flag) {
process = readyList.get(0);
readyList.remove(0);
}
System.out.println("进程" + process.id + "执行");
flag = true;
//进程执行完成
if (process.exeTime == process.time) {
endQueue.offer(process);
process.roundTime = time - process.arriveTime;
process.finshTime = time;
process.aveRoundTime = (process.roundTime + 0.0) / process.exeTime;
System.out.println("进程" + process.id + "执行完成");
flag = false;
}
time++;
process.exeTime++;
System.out.println(time + "s:");
//执行结束
if (readyList.isEmpty() & flag == false) {
size = endQueue.size();
for (process p : endQueue) {
total = total + p.aveRoundTime;
System.out.println("进程:" + p.id + "\t进程优先级:\t" + p.priority + "\t完成时间:\t" + p.finshTime
+ "\t周转时间:\t" + p.roundTime +
"\t带权周转时间:\t" + p.aveRoundTime + "\n");
}
System.out.println("平均带权周转时间:\t" + (total / size));
return;
}
}
}
public static void SJF(ArrayList<process> processes) {
Queue<process> endQueue = new LinkedList<>();
ArrayList<process> readyList = new ArrayList<>();
int time = 0;
int size;
double total = 0;
boolean flag = false;
process process = null;
System.out.println(time + "s:");
while (endQueue.size() < processes.size()) {
// 是否有队列到达
for (int i = 0; i < processes.size(); i++) {
// 控制进程到达准备队列
if (processes.get(i).arriveTime == time) {
processes.get(i).beginTime = time;
System.out.println("进程" + (i+1) + "到达");
readyList.add(processes.get(i));
//使用冒泡排序,将进入数组中的进程按优先级排序
Sort.BubbleSort(readyList);
}
}
// 进程执行
if (!flag) {
process = readyList.get(0);
readyList.remove(0);
}
System.out.println("进程" + process.id + "执行");
flag = true;
//进程执行完成
if (process.exeTime == process.time) {
endQueue.offer(process);
process.roundTime = time - process.arriveTime;
process.finshTime = time;
process.aveRoundTime = (process.roundTime + 0.0) / process.exeTime;
System.out.println("进程" + process.id + "执行完成");
flag = false;
}
time++;
process.exeTime++;
System.out.println(time + "s:");
//执行结束
if (readyList.isEmpty() & flag == false) {
size = endQueue.size();
for (process p : endQueue) {
total = total + p.aveRoundTime;
System.out.println("进程:" + p.id + "\t进程优先级:\t" + p.priority + "\t完成时间:\t" + p.finshTime
+ "\t周转时间:\t" + p.roundTime +
"\t带权周转时间:\t" + p.aveRoundTime + "\n");
}
System.out.println("平均带权周转时间:\t" + (total / size));
return;
}
}
}
}
public class Sort {
public static void BubbleSort(ArrayList<process> processes){
if(processes==null||processes.size()<2)
return;
for (int i = processes.size()-1; i >0; i--) {
for (int j = 0; j < i; j++) {
if(processes.get(j).priority<processes.get(j+1).priority){
Collections.swap(processes,j,j+1);
}
}
}
}
public static void HRNSort(ArrayList<process> processes,int now){
if (processes==null||processes.size()<2)
return;
float first= (processes.get(0).time+now-processes.get(0).arriveTime)/processes.get(0).time;
for (int i = processes.size()-1; i >0; i--) {
float power=(processes.get(i).time+now-processes.get(i).arriveTime)/processes.get(i).time;
if(first<power)
Collections.swap(processes,0,i);
}
}
public class PrintSth {
public static void menu(){
System.out.println("|-------------------------------------------------------|\n");
System.out.println("|模拟进程执行小程序: |\n");
System.out.println("|1.创建进程 |\n");
System.out.println("|2.查看现有进程 |\n");
System.out.println("|3.撤销进程 |\n");
System.out.println("|4.执行进程 |\n");
System.out.println("|5.退出进程 |\n");
System.out.println("|------------------------------------------------------|\n");
System.out.println("请输入操作指令:\n");
}
public static void excutionmenu(){
System.out.println("执行选项:\n");
System.out.println("1.先来先服务\n");
System.out.println("2.短线程优先\n");
System.out.println("3.时间片轮转调度\n");
System.out.println("4.高响应比有先调度\n");
System.out.println("5.返回到上一步\n");
System.out.println("请选择运行的方式:");
}
public static void excution(){
System.out.println(
//打印正在执行的进程信息
"进程名称"+"进程到达时间:"+"进程状态:"+"进程剩余执行时间:");
}
public static void excutionlist(){
System.out.println("进程列表:");
System.out.println("进程名:"+"进程状态:"+"进程到达时间"+"进程执行时间");
}
}
2.运行截图
主菜单
执行菜单:
(1)先来先服务:
a.随机生成测试数据:
b.运行过程的部分动态演示
c.运行结果
(2)短进程优先
a.测试数据
b.动态演示部分截图
c.运行结果图
(3)轮转法
a.测试数据
b.动态演示:
c.运行结果
(4)最高响应比优先
a.测试数据
b.动态演示:
c.运行结果