实验五 模拟调度时间片
前言
相关知识
先到先服务(FCFS):按照进程提交给系统的先后次序来进行调度
短作业优先(SJF/SPF):按照进程所要求的运行时间来衡量
时间片轮转:根据先来先服务排序,以一个时间片为单位,依次执行不同的进程
最高优先权优先调度算法(HRRN):为每个作业设置一个优先权(响应比),调度之前先计算各作业的优先权,优先数高者优先调度RP(响应比)=作业周转时间/作业运行时间=1+作业等待时间/作业运行时间
计算
周转时间=作业完成时刻-作业到达时刻
带权周转时间=周转时间/服务时间
平均周转时间=作业周转总时间/作业个数
平均带权周转时间=带权周转总时间/作业个数
实验目的
用高级语言编写和调试进程调度的模拟程序,以加深对进程调度算法的理解
实验内容
1、 自定义进程相关的数据结构
2、 实现先来先服务算法、时间片轮转算法、最高优先权优先调度算法、最短进程优先调度算法
3、 测试以上进程调度策略的周转时间、带权周转时间、平均周转时间和平均带权周转时间,并定性评价它们的性能
实验步骤
菜单
public static void runattribute(attribute[] ab) { System.out.println("请选择排序方式"); Scanner in = new Scanner(System.in); int n = -1; while (n != 0) { System.out.println("1.先到先服务 2.最短进程优先 3.时间片转轮 4.抢占式高优先权 0退出"); n = in.nextInt(); switch (n) { case 1: ab = InputTimesort(ab); OutputAttribute(ab); break; case 2: ab = Short_jobs_take_precedence(ab, 0, 0); OutputAttribute(ab); break; case 3: System.out.println("请输入时间片时间"); n = in.nextInt(); Time_slice_rotation(ab, n); break; case 4: ab = priorityTimesort(ab, 0, 0); OutputAttribute(ab); break; } } return; }
|
为进程定义一个对象
class attribute { static int runname = -1; int Run_time; int input_time; int name = -1;
public int getName() { return name; }
public void setName(int name) { this.name = name; }
public attribute() { }
public attribute(int input_time, int run_time) { this.Run_time = run_time; this.input_time = input_time; runname++; this.name = runname + 0;
}
public int getRun_time() { return Run_time; }
public void setRun_time(int run_time) { Run_time = run_time; }
public int getInput_time() { return input_time; }
public void setInput_time(int input_time) { this.input_time = input_time; } }
|
先来先服务
private static attribute[] InputTimesort(attribute[] ab) { for (int i = 0; i < ab.length; i++) { int min = i; for (int J = i; J < ab.length; J++) { if (ab[J].getInput_time() < ab[i].getInput_time()) { min = J; } } swat(ab, i, min); } return ab; }
|
最短进程优先
private static attribute[] Short_jobs_take_precedence(attribute[] ab, int i, int Begin) { int min_Run_time = -1; int min_input_time = i; int index = -1; for (int j = Begin; j < ab.length; j++) { if (ab[j].input_time <= i) { if (min_Run_time == -1) { index = j; min_Run_time = ab[j].Run_time; } else { if (min_Run_time > ab[j].Run_time) { index = j; min_Run_time = ab[j].Run_time; } } } } if (index == -1) { min_Run_time = ab[Begin].Run_time; min_input_time = ab[Begin].input_time; index = Begin; for (int j = Begin; j < ab.length; j++) { if (ab[j].input_time < min_input_time) { min_input_time = ab[j].input_time; index = j; min_Run_time = ab[j].Run_time; } else { if (ab[j].input_time == min_input_time) { if (min_Run_time < ab[j].Run_time) { min_input_time = ab[j].input_time; index = j; min_Run_time = ab[j].Run_time; } } } } } swat(ab, Begin, index); if (Begin + 1 == ab.length) { return ab; } Short_jobs_take_precedence(ab, (min_input_time > i ? min_input_time : i) + min_Run_time, Begin + 1); return ab; }
|
时间片轮转
private static attribute[] Time_slice_rotation(attribute[] ab, int n) { int[] Alltime = new int[ab.length]; for (int j = 0; j < ab.length; j++) { Alltime[j] = ab[j].Run_time; } int[] complete_Alltime = new int[ab.length]; int min_input_time = -1; int index; int complete = 0; int N = 1; while (complete < ab.length) { index = -1; for (int i = 0; i < ab.length; i++) { if (ab[i].input_time >= N * n) { continue; } if (Alltime[i] <= complete_Alltime[i]) { continue; } if (index == -1) { index = i; min_input_time = ab[i].input_time; } if (ab[i].input_time < min_input_time) { index = i; } } if (index != -1) { if (ab[index].input_time > N * n - n) { complete_Alltime[index] = N * n - ab[index].input_time; } else { complete_Alltime[index] += n; }
if (Alltime[index] <= complete_Alltime[index]) { complete++; complete_Alltime[index] = Alltime[index]; } System.out.println("第" + N + "个时间片 运行进程" + ab[index].name + "进度为 " + complete_Alltime[index] + "/" + Alltime[index]); } else { System.out.println("第" + N + "个时间片 暂无进程进入");
} N++; } return null; }
|
抢占式高优先权
private static attribute[] priorityTimesort(attribute[] ab, int i, int Begin) { int min_Run_time = -1; int min_input_time = i; int min_priority = 0; int index = -1; for (int j = Begin; j < ab.length; j++) { if (ab[j].input_time <= min_input_time) { if (min_Run_time == -1) { index = j; min_Run_time = ab[j].Run_time; min_priority = (ab[j].input_time - i) / ab[j].Run_time; } else { if (min_priority > (ab[j].input_time - i) / ab[j].Run_time) { index = j; min_Run_time = ab[j].Run_time; min_priority = (ab[j].input_time - i) / ab[j].Run_time; } } } } if (index == -1) { min_Run_time = ab[Begin].Run_time; min_input_time = ab[Begin].input_time; index = Begin; for (int j = Begin; j < ab.length; j++) { if (ab[j].input_time < min_input_time) { min_input_time = ab[j].input_time; index = j; min_Run_time = ab[j].Run_time; } else { if (ab[j].input_time == min_input_time) { if (min_input_time < ab[j].Run_time) { min_input_time = ab[j].input_time; index = j; min_Run_time = ab[j].Run_time; } } } } } swat(ab, Begin, index); if (Begin + 1 == ab.length) { return ab; } priorityTimesort(ab, (min_input_time > i ? min_input_time : i) + min_Run_time, Begin + 1); return ab; }
|
置换数组位置
public static void swat(attribute[] ab, int i, int index) { attribute a = ab[i]; ab[i] = ab[index]; ab[index] = a; }
|
结果输出
public static void OutputAttribute(attribute[] ab) { int time = ab[0].input_time; int TimeSum[] = new int[ab.length]; double DTimeSum[] = new double[ab.length]; System.out.print("进程ID "); System.out.print("到达时间 "); System.out.print("服务时间 "); System.out.print("完成时间 "); System.out.print("周转时间 "); System.out.print("带权周转时间 \n"); for (int i = 0; i < ab.length; i++) { if (ab[i].input_time > time) { time = ab[i].input_time; }
System.out.print(ab[i].name + "\t "); System.out.print(ab[i].input_time + "\t "); time += ab[i].Run_time; System.out.print(ab[i].Run_time + "\t "); System.out.print(time + "\t "); TimeSum[i] = (time - ab[i].input_time); System.out.print(TimeSum[i] + "\t "); DTimeSum[i] = (double)(TimeSum[i] / ab[i].Run_time);
System.out.print(DTimeSum[i]); System.out.println(); } System.out.println("周转总时间:" + Arrays.stream(TimeSum).sum()); System.out.println("平均周转时间:" + (double)Arrays.stream(TimeSum).sum()/ab.length); System.out.println("带权周转总时间:" + Arrays.stream(DTimeSum).sum()); System.out.println("平均带权周转时间:" + Arrays.stream(DTimeSum).sum()/ab.length); }
|
主函数
public class 模拟调度时间片 { public static void main(String[] args) { attribute[] ab = { new attribute(1, 5), new attribute(8, 5), new attribute(10, 5), new attribute(16, 15), new attribute(14, 25) }; utils.runattribute(ab); } }
|
完整代码
package 操作系统实验;
import java.text.DecimalFormat; import java.util.Arrays; import java.util.Scanner;
public class 模拟调度时间片 { public static void main(String[] args) { attribute[] ab = { new attribute(1, 5), new attribute(8, 5), new attribute(10, 5), new attribute(16, 15), new attribute(14, 25) }; utils.runattribute(ab); } }
class attribute { static int runname = -1; int Run_time; int input_time; int name = -1;
public int getName() { return name; }
public void setName(int name) { this.name = name; }
public attribute() { }
public attribute(int input_time, int run_time) { this.Run_time = run_time; this.input_time = input_time; runname++; this.name = runname + 0;
}
public int getRun_time() { return Run_time; }
public void setRun_time(int run_time) { Run_time = run_time; }
public int getInput_time() { return input_time; }
public void setInput_time(int input_time) { this.input_time = input_time; } }
class utils { public static void OutputAttribute(attribute[] ab) { int time = ab[0].input_time; int TimeSum[] = new int[ab.length]; double DTimeSum[] = new double[ab.length]; System.out.print("进程ID "); System.out.print("到达时间 "); System.out.print("服务时间 "); System.out.print("完成时间 "); System.out.print("周转时间 "); System.out.print("带权周转时间 \n"); for (int i = 0; i < ab.length; i++) { if (ab[i].input_time > time) { time = ab[i].input_time; }
System.out.print(ab[i].name + "\t "); System.out.print(ab[i].input_time + "\t "); time += ab[i].Run_time; System.out.print(ab[i].Run_time + "\t "); System.out.print(time + "\t "); TimeSum[i] = (time - ab[i].input_time); System.out.print(TimeSum[i] + "\t "); DTimeSum[i] = (double)(TimeSum[i] / ab[i].Run_time);
System.out.print(DTimeSum[i]); System.out.println(); } System.out.println("周转总时间:" + Arrays.stream(TimeSum).sum()); System.out.println("平均周转时间:" + (double)Arrays.stream(TimeSum).sum()/ab.length); System.out.println("带权周转总时间:" + Arrays.stream(DTimeSum).sum()); System.out.println("平均带权周转时间:" + Arrays.stream(DTimeSum).sum()/ab.length); }
public static void runattribute(attribute[] ab) { System.out.println("请选择排序方式"); Scanner in = new Scanner(System.in); int n = -1; while (n != 0) { System.out.println("1.先到先服务 2.最短进程优先 3.时间片转轮 4.抢占式高优先权 0退出"); n = in.nextInt(); switch (n) { case 1: ab = InputTimesort(ab); OutputAttribute(ab); break; case 2: ab = Short_jobs_take_precedence(ab, 0, 0); OutputAttribute(ab); break; case 3: System.out.println("请输入时间片时间"); n = in.nextInt(); Time_slice_rotation(ab, n); break; case 4: ab = priorityTimesort(ab, 0, 0); OutputAttribute(ab); break; } } return; }
private static attribute[] InputTimesort(attribute[] ab) { for (int i = 0; i < ab.length; i++) { int min = i; for (int J = i; J < ab.length; J++) { if (ab[J].getInput_time() < ab[i].getInput_time()) { min = J; } } swat(ab, i, min); } return ab; }
private static attribute[] Short_jobs_take_precedence(attribute[] ab, int i, int Begin) { int min_Run_time = -1; int min_input_time = i; int index = -1; for (int j = Begin; j < ab.length; j++) { if (ab[j].input_time <= i) { if (min_Run_time == -1) { index = j; min_Run_time = ab[j].Run_time; } else { if (min_Run_time > ab[j].Run_time) { index = j; min_Run_time = ab[j].Run_time; } } } } if (index == -1) { min_Run_time = ab[Begin].Run_time; min_input_time = ab[Begin].input_time; index = Begin; for (int j = Begin; j < ab.length; j++) { if (ab[j].input_time < min_input_time) { min_input_time = ab[j].input_time; index = j; min_Run_time = ab[j].Run_time; } else { if (ab[j].input_time == min_input_time) { if (min_Run_time < ab[j].Run_time) { min_input_time = ab[j].input_time; index = j; min_Run_time = ab[j].Run_time; } } } } } swat(ab, Begin, index); if (Begin + 1 == ab.length) { return ab; } Short_jobs_take_precedence(ab, (min_input_time > i ? min_input_time : i) + min_Run_time, Begin + 1); return ab; } public static void swat(attribute[] ab, int i, int index) { attribute a = ab[i]; ab[i] = ab[index]; ab[index] = a; }
private static attribute[] Time_slice_rotation(attribute[] ab, int n) { int[] Alltime = new int[ab.length]; for (int j = 0; j < ab.length; j++) { Alltime[j] = ab[j].Run_time; } int[] complete_Alltime = new int[ab.length]; int min_input_time = -1; int index; int complete = 0; int N = 1; while (complete < ab.length) { index = -1; for (int i = 0; i < ab.length; i++) { if (ab[i].input_time >= N * n) { continue; } if (Alltime[i] <= complete_Alltime[i]) { continue; } if (index == -1) { index = i; min_input_time = ab[i].input_time; } if (ab[i].input_time < min_input_time) { index = i; } } if (index != -1) { if (ab[index].input_time > N * n - n) { complete_Alltime[index] = N * n - ab[index].input_time; } else { complete_Alltime[index] += n; }
if (Alltime[index] <= complete_Alltime[index]) { complete++; complete_Alltime[index] = Alltime[index]; } System.out.println("第" + N + "个时间片 运行进程" + ab[index].name + "进度为 " + complete_Alltime[index] + "/" + Alltime[index]); } else { System.out.println("第" + N + "个时间片 暂无进程进入");
} N++; } return null; }
private static attribute[] priorityTimesort(attribute[] ab, int i, int Begin) { int min_Run_time = -1; int min_input_time = i; int min_priority = 0; int index = -1; for (int j = Begin; j < ab.length; j++) { if (ab[j].input_time <= min_input_time) { if (min_Run_time == -1) { index = j; min_Run_time = ab[j].Run_time; min_priority = (ab[j].input_time - i) / ab[j].Run_time; } else { if (min_priority > (ab[j].input_time - i) / ab[j].Run_time) { index = j; min_Run_time = ab[j].Run_time; min_priority = (ab[j].input_time - i) / ab[j].Run_time; } } } } if (index == -1) { min_Run_time = ab[Begin].Run_time; min_input_time = ab[Begin].input_time; index = Begin; for (int j = Begin; j < ab.length; j++) { if (ab[j].input_time < min_input_time) { min_input_time = ab[j].input_time; index = j; min_Run_time = ab[j].Run_time; } else { if (ab[j].input_time == min_input_time) { if (min_input_time < ab[j].Run_time) { min_input_time = ab[j].input_time; index = j; min_Run_time = ab[j].Run_time; } } } } } swat(ab, Begin, index); if (Begin + 1 == ab.length) { return ab; } priorityTimesort(ab, (min_input_time > i ? min_input_time : i) + min_Run_time, Begin + 1); return ab; } }
|
运行结果
先来先服务

最短进程优先

时间片轮转

抢占式高优先权

学习到的新东西
实验三学习了如何输出数组,数组的值传递,今天查到了如何调用API进行数组的一些计算
int[] arr1 = {1, 5, 3, 6, 7}; int sum = Arrays.stream(arr1).sum(); OptionalDouble avg = Arrays.stream(arr1).average(); double average = avg.getAsDouble(); int min = Arrays.stream(arr1).min().getAsInt(); int max = Arrays.stream(arr1).max().getAsInt(); System.out.println("arr1 和 = " + sum + ", 平均值 = " + average + ", 最小值 = " + min + ", 最大值 = " + max);
|

总结
先来先服务算法:该算法思想是按照进入就绪队列的先后次序来分配处理机。采用非剥夺调度方式,即一旦某个进程占有处理机,就一直运行下去,直到该进程完成其工作或因等待某一事件而不能继续执行时才释放处理机
① 该算法原理简单,易于实现
② 各进程平等竞争
③ 由于各进程执行的时间不一样,从而导致相对不公平现象的产生
④ 该算法有利于长进程,不利于短进程
⑤ 该算法很少用来作为主调度策略,常常用作辅助调度算法使用
短作业优先:按照进程所要求的运行时间来衡量。但对长作业不利,可能导致饥饿,难以做到真正的短作业优先
最高优先权优先调度算法:为每个作业设置一个优先权(响应比),调度之前先计算各作业的优先权。上述两种算法的权衡折中,综合考虑等待时间和运行时间。
时间片轮转:根据先来先服务排序,以一个时间片为单位,依次执行不同的进程。公平,适用于分时系统,但频繁切换有开销,不区分优先级
附王道考研知识点总结
