作业调度
本文主要介绍了OS作业调度的三种算法(FCFS SJF HRN),希望对您有所帮助
一. 实验目的
- 掌握作业调度的基本思想
- 熟练使用各种作业调度算法描述的过程
- 掌握各种算法的优缺点
- 提高理论和实践结合的能力
二. 实验内容
- FCFS 先来先服务
- SJF 最短作业优先
- HRN 最高响应比优先算法
三. 实验环境
- 实践平台 windows
- 编写环境 java
- 编译器 idea
四. 实验设计原理
FCFS:先来先服务
根据作业进入的先后顺序来进行调度,最先进的最先执行
SJF:最短作业优先
根据执行所需的时间来确定下一个执行的作业
HRN:最高相应比优先
根据作业的响应比选出最高的那个对应的作业执行
五. 实验详细实现过程和算法流程
FCFS 先来先服务
SJF 最短作业优先
HRN 最高相应比优先
六. 实验调试与结果分析
FCFS
SJF
HRN
七. 源代码
job类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class job {
public int index;//job序列号
public int arriveTime;//到达时间
public int serviceTime;//执行总时间
public int startTime =0;//开始执行时间
public int finishTime =0;//结束时间
public int turnTime =0;//周转时间
public double powerTime =0;//带权周转时间
public job(int index,int arriveTime, int serviceTime){
this.index = index;
this.arriveTime = arriveTime;
this.serviceTime = serviceTime;
}
public void display(){
System.out.println(" "+index+" "+arriveTime+" "+serviceTime+" "+startTime+" "+finishTime+" "+turnTime+" "+powerTime);
}
}主类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
public class test {
public static int digitToTime(int a,int b){//计算时间求和换算
int ans = 0;
int h = a/100;
int m = a%100;
h += (m+b)/60;
m = (m+b)%60;
ans = h*100 + m;
return ans;
}
public static int subTime(int a,int b){//计算时间差值
int h1 = a/100;
int m1 = a%100;
int h2 = b/100;
int m2 = b%100;
int t1 = h1*60+m1;
int t2 = h2*60+m2;
return t1-t2;
}
public static void FCFS(job[] data){//先来先服务
int preFinishTime = 0; // 前一个作业的完成时间即为下一个作业的开始时间
preFinishTime = data[0].arriveTime;//初始化前一个完成时间
for (job datum : data) {
//开始时间等于上一个完成时间
datum.startTime = preFinishTime;
// 作业的完成时间为上一个作业的完成时间加当前作业的服务时间
datum.finishTime = digitToTime(preFinishTime,datum.serviceTime) ;
preFinishTime = datum.finishTime;
// 周转时间 = 完成时间 - 到达时间
datum.turnTime = subTime(datum.finishTime,datum.arriveTime);
// 带权周转时间 = 作业的周转时间 / 系统提供服务的时间
datum.powerTime = (double) datum.turnTime / datum.serviceTime;
}
ansDisplay(data);
}
public static void SJF(job[] data){//短作业优先
int preFinishTime = 0; // 前一个作业的完成时间即为下一个作业的开始时间
preFinishTime = data[0].arriveTime;//初始化前一个完成时间
int index=0;
for(int i=0;i<data.length;i++){//这一层for循环实际起的作用是作业次数
int min_job = 999;
for (int j=0;j<data.length;j++){//这一层循环判断所有作业中还未执行的最短作业
//判断条件
//还未执行
//比min_job还要小才可更换
//到达时间小于上一个完成时间
if(data[j].startTime==0 && data[j].serviceTime<min_job && data[j].arriveTime<=preFinishTime){
min_job = data[j].serviceTime;
index = j;//循环结束后得到下一次作业的index
}
}
//与上面的一致 根本区别就是循环选取的不是早到的那个 而是最短的那个
data[index].startTime = preFinishTime;
data[index].finishTime = digitToTime(preFinishTime,data[index].serviceTime);
preFinishTime = data[index].finishTime;
data[index].turnTime = subTime(data[index].finishTime,data[index].arriveTime);
data[index].powerTime = (double) data[index].turnTime / data[index].serviceTime;
}
ansDisplay(data);
}
public static void HRN(job[] data){//最高响应比优先
int preFinishTime = 0; // 前一个作业的完成时间即为下一个作业的开始时间
preFinishTime = data[0].arriveTime;//初始化前一个完成时间
int index=0;
for(int i=0;i<data.length;i++){//这一层for循环实际起的作用是作业次数
double max_response = 0;
for (int j=0;j<data.length;j++){//这一层循环判断所有作业中还未执行的响应比最高的作业
//判断条件
//还未执行
//到达时间小于上一个完成时间
if(data[j].startTime==0 && data[j].arriveTime<=preFinishTime){
//比max_response大才可更换
double response = (digitToTime(preFinishTime,data[j].serviceTime)-data[j].arriveTime) / (double)data[j].serviceTime;
if(response>max_response){
index = j;//循环结束后得到下一次作业的index
max_response = response;
}
}
}
data[index].startTime = preFinishTime;
data[index].finishTime = digitToTime(preFinishTime,data[index].serviceTime);
preFinishTime = data[index].finishTime;
data[index].turnTime = subTime(data[index].finishTime,data[index].arriveTime);
data[index].powerTime = (double) data[index].turnTime / data[index].serviceTime;
}
ansDisplay(data);
}
public static void ansDisplay(job[] data){
double avgTurnTime = 0;
double avgPowerTime = 0;
System.out.println("作业序号\t"+"到达时间\t" + "执行总时间\t" + "开始执行时间\t" + "结束时间\t" + "周转时间\t" + "带权周转时间\t");
for (job datum : data) {
avgTurnTime += datum.turnTime;
avgPowerTime += datum.powerTime;
datum.display();
}
avgTurnTime /= data.length;
avgPowerTime /= data.length;
System.out.println("平均周转时间"+avgTurnTime);
System.out.println("平均带权周转时间"+avgPowerTime);
}
public static void main(String[] args) {
int way;
Scanner stdin = new Scanner(System.in);
System.out.println("请输入调度方式(1.FCFS 2.SJF 3.HRN)");
way = stdin.nextInt();
int sum;
System.out.println("请输入作业数");
sum = stdin.nextInt();
job[] data = new job[sum];
System.out.println("请输入作业数据(1 800 50)");
for(int i =0; i <sum; i++){
int a,b,c;
a = stdin.nextInt();
b = stdin.nextInt();
c = stdin.nextInt();
data[i] = new job(a,b,c);
}
// 测试读入代码
// for(int i=0;i<sum;i++){
// data[i].display();
// }
if(way == 1)
FCFS(data);
else if(way == 2)
SJF(data);
else
HRN(data);
}
}
作业调度
http://kaikai12321.github.io/2022/11/20/作业调度/