25 Nov 2017
操作系统处理机调度算法模拟实现-Notzuonotdied
简介
多道程序设计中,经常是若干个进程同时处于就绪状态,为了使系统中的各进程有条不紊地运行,必须选择某种调度策略,以选择一个进程占用处理机。
思路分析
由于本实验是按照处理机调度算法模拟实现处理机的调度,与真正的处理机调度过程不完全相同,比如没有实现中断,进程的运行也不是真正的运行,而是在屏幕上打印其运行时间等。
大致思路:
- 建立三个队列:PCB队列,就绪队列,完成队列。
- PCB队列:保存将进入系统的进程。(由于没有实现中断,所以将进入系统运行的进程必须在程序运行前给出)。
- 就绪队列:到达进程进入系统的时间,将该进程放入就绪队列,等待调度。
- 完成队列:将“运行”完的进程放入完成队列。
- 进程运行过程是在屏幕上打印相关信息。
- 使用轮转算法调度的进程应打印的信息包括:进程占用处理机序列,该进程每次占用处理机的开始时间与结束时间。
- 统计出进程的周转时间T和带权周转时间W。
大致流程图
实现
public class OSRR {
public static void main(String[] args) {
new RR();
}
}
class RR {
private Queue<RRBean> PCBQueue;
private LinkedList<RRBean> ReadyQueue;
private Queue<RRBean> CompleteQueue;
// 定义时间片的长度
private static final int SLICETIME = 4;
// 定义总的运行时间
private int time;
RR() {
time = 0;
InitQueue();
InitBean();
StartProcess();
showResult();
}
private void StartProcess() {
System.out.println("PCB进程数" + PCBQueue.size());
StringBuilder sb = new StringBuilder();
sb.append("运行过程:");
while (true) {
// 是否所有进程运行完
if (PCBQueue.size() == 0 && ReadyQueue.size() == 0) {
// 如果所有进程都运行完了,就终止程序
break;
}
// 是否有新的进程进入系统
for (RRBean r : PCBQueue) {
// 新的进程进入就绪队列
if (r.arrive_time <= time) {
ReadyQueue.addFirst(r);
PCBQueue.remove(r);
break;
}
}
// 就绪队列不为空的时候
if (ReadyQueue.size() != 0) {
// 取出一个进程运行
RRBean r = ReadyQueue.poll();
r.run_time += SLICETIME;
int temp = time;
// 如果时间片用完之后,
if (r.run_time >= r.time) {
time += r.time - r.run_time + SLICETIME;
r.endTime = time;
// 该进程已经完成了
CompleteQueue.offer(r);
} else {
time += SLICETIME;
// 该进程没有完成
ReadyQueue.offer(r);
}
System.out.println("进程号:" + r.id +
",本次开始时间:" + temp + ",本次结束时间:" + time);
sb.append(r.id);
sb.append("->");
} else {
++time;
}
}
sb.delete(sb.length() - 2, sb.length());
System.out.println(sb.toString());
}
private void showResult() {
System.out.println("××××××××最后的结果:××××××××");
for (RRBean rrBean : CompleteQueue) {
System.out.println("进程号:" + rrBean.id + ",周转时间为:" +
(rrBean.endTime - rrBean.arrive_time) + ",平均周转时间:" +
(float) (rrBean.endTime - rrBean.arrive_time) / rrBean.time);
}
}
private void InitQueue() {
PCBQueue = new LinkedList<>();
ReadyQueue = new LinkedList<>();
CompleteQueue = new LinkedList<>();
}
private void InitBean() {
File file = new File("./src/Schedule/rr1.txt");
BufferedReader br = null;
String read;
try {
System.out.println("进程ID\t到达时间\t估计运行时间\t优先级");
br = new BufferedReader(new FileReader(file));
while ((read = br.readLine()) != null) {
RRBean rrBean = new RRBean();
rrBean.init(read);
PCBQueue.offer(rrBean);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
System.out.println("文件不存在");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
class RRBean {
//进程号
int id;
//进程状态 0-Ready, 1-Run, 2-Finish
int status;
//进程到达时间
int arrive_time;
//估计运行时间
int time;
//已运行时间
int run_time;
//等待时间
int wait_time;
//优先级
int priority;
// 结束时间
int endTime;
void init(String initString) {
List<String> num = new ArrayList<>();
Pattern pattern = Pattern.compile("-*\\d+(\\.\\d+)?");
Matcher matcher = pattern.matcher(initString);
while (matcher.find()) {
num.add(matcher.group());
}
StringBuilder sb = new StringBuilder();
for (String string : num) {
sb.append(string);
sb.append("\t\t");
}
System.out.println(sb.toString());
this.id = Integer.parseInt(num.get(0));
this.arrive_time = Integer.parseInt(num.get(1));
this.time = Integer.parseInt(num.get(2));
this.priority = Integer.parseInt(num.get(3));
this.status = 0;
this.run_time = 0;
this.wait_time = 0;
}
}
情况1
备注:进程ID、到达时间、估计运行时间、优先级
0 2 30 2
1 2 60 4
2 15 15 0
3 26 28 5
4 80 19 1
5 90 8 7
输出结果:(备注:时间片为10)
进程ID 到达时间 估计运行时间 优先级
0 2 30 2
1 2 60 4
2 15 15 0
3 26 28 5
4 80 19 1
5 90 8 7
PCB进程数6
进程号:0,本次开始时间:2,本次结束时间:12
进程号:1,本次开始时间:12,本次结束时间:22
进程号:2,本次开始时间:22,本次结束时间:32
进程号:3,本次开始时间:32,本次结束时间:42
进程号:0,本次开始时间:42,本次结束时间:52
进程号:1,本次开始时间:52,本次结束时间:62
进程号:2,本次开始时间:62,本次结束时间:67
进程号:3,本次开始时间:67,本次结束时间:77
进程号:0,本次开始时间:77,本次结束时间:87
进程号:4,本次开始时间:87,本次结束时间:97
进程号:5,本次开始时间:97,本次结束时间:105
进程号:1,本次开始时间:105,本次结束时间:115
进程号:3,本次开始时间:115,本次结束时间:123
进程号:4,本次开始时间:123,本次结束时间:132
进程号:1,本次开始时间:132,本次结束时间:142
进程号:1,本次开始时间:142,本次结束时间:152
进程号:1,本次开始时间:152,本次结束时间:162
运行过程:0->1->2->3->0->1->2->3->0->4->5->1->3->4->1->1->1
××××××××最后的结果:××××××××
进程号:2,周转时间为:52,平均周转时间:3.4666667
进程号:0,周转时间为:85,平均周转时间:2.8333333
进程号:5,周转时间为:15,平均周转时间:1.875
进程号:3,周转时间为:97,平均周转时间:3.4642856
进程号:4,周转时间为:52,平均周转时间:2.7368422
进程号:1,周转时间为:160,平均周转时间:2.6666667
情况2
备注:进程ID、到达时间、估计运行时间、优先级
0 0 4 2
1 1 3 4
2 2 4 0
3 3 2 5
4 4 4 1
输出结果:(备注:时间片为1)
进程ID 到达时间 估计运行时间 优先级
0 0 4 2
1 1 3 4
2 2 4 0
3 3 2 5
4 4 4 1
PCB进程数5
进程号:0,本次开始时间:0,本次结束时间:1
进程号:1,本次开始时间:1,本次结束时间:2
进程号:2,本次开始时间:2,本次结束时间:3
进程号:3,本次开始时间:3,本次结束时间:4
进程号:4,本次开始时间:4,本次结束时间:5
进程号:0,本次开始时间:5,本次结束时间:6
进程号:1,本次开始时间:6,本次结束时间:7
进程号:2,本次开始时间:7,本次结束时间:8
进程号:3,本次开始时间:8,本次结束时间:9
进程号:4,本次开始时间:9,本次结束时间:10
进程号:0,本次开始时间:10,本次结束时间:11
进程号:1,本次开始时间:11,本次结束时间:12
进程号:2,本次开始时间:12,本次结束时间:13
进程号:4,本次开始时间:13,本次结束时间:14
进程号:0,本次开始时间:14,本次结束时间:15
进程号:2,本次开始时间:15,本次结束时间:16
进程号:4,本次开始时间:16,本次结束时间:17
运行过程:0->1->2->3->4->0->1->2->3->4->0->1->2->4->0->2->4
××××××××最后的结果:××××××××
进程号:3,周转时间为:6,平均周转时间:3.0
进程号:1,周转时间为:11,平均周转时间:3.6666667
进程号:0,周转时间为:15,平均周转时间:3.75
进程号:2,周转时间为:14,平均周转时间:3.5
进程号:4,周转时间为:13,平均周转时间:3.25
输出结果:(备注:时间片为4)
进程ID 到达时间 估计运行时间 优先级
0 0 4 2
1 1 3 4
2 2 4 0
3 3 2 5
4 4 4 1
PCB进程数5
进程号:0,本次开始时间:0,本次结束时间:4
进程号:1,本次开始时间:4,本次结束时间:7
进程号:2,本次开始时间:7,本次结束时间:11
进程号:3,本次开始时间:11,本次结束时间:13
进程号:4,本次开始时间:13,本次结束时间:17
运行过程:0->1->2->3->4
××××××××最后的结果:××××××××
进程号:0,周转时间为:4,平均周转时间:1.0
进程号:1,周转时间为:6,平均周转时间:2.0
进程号:2,周转时间为:9,平均周转时间:2.25
进程号:3,周转时间为:10,平均周转时间:5.0
进程号:4,周转时间为:13,平均周转时间:3.25
Til next time,
LinkWorld
at 18:56