本文作者偷懒了 没有写cpu和io的输入输出~
要求:
输入:
若干程序文件,例如 Prog1, Prog2,…, Progk。每个程序文件 Progi的格式如下(每一行表示一条
指令):
cpu
cpu
io
cpu
cpu
…
输出:
第1列是时间,第2-6列是k=6个进程的状态(READY,RUN:io,RUN:cpu,WAITING,DONE),
第 7 列是 cpu 的状态,第 8 列是 IO 设备状态
额外:(1) 同时支持 cpu 和 io 指令,以及多个进程并发执行
基本假设:
⚫ 单处理机,即一次只能 1 个进程处于运行态
⚫ 内核实现进程切换和进程调度(scheduler&switch)的执行时间忽略,只考虑进程的执
行所花时间
⚫ 程序的指令分为 cpu 和 io 两种类型。 cpu 代表 cpu 指令,执行 cpu 指令需要 1 个时间
单位;io 代表 io 指令,需要阻塞该进程,执行 io 指令需要 5 个时间单位(其中,第 1 个
时间单位使用 cpu,后面 4 个时间单位使用 IO 设备)
⚫ 进程的状态有:READY,RUN:cpu, RUN:io, WAITING, DONE
⚫ CPU 的状态有:1(忙),null(空闲)
⚫ IOs 的状态有:1(忙),null(空闲)
实现
事实上这个模拟程序以读入文件中的指令为最佳,但是作者比较懒 不必要的地方就跳过去了没有写~
- 首先按照程序的要求分析,我们可以将进程写成一个类,将资源管理器写成一个类,将主类当作操作系统,否则在写这个程序的时候容易无从下手。
- process类要满足实验的基本需求,它应该知道自己该保存多少条CPU指令,多少条CPU:IO指令,然后一个IO指令生成对应的4条waiting指令。
- 主类模拟的是OS,也就是说进程管理主要是它进行的,所以就是它负责进程调度了,它需要知道每一个进程实时的运行状态(就绪、等待、占用CPU、占用CPU并且是CPU:IO指令、完成)
- 本程序的核心思想是设计三个栈:就绪栈、等待栈、运行栈,三个栈都空了说明程序运行结束了
- 主程序执行流程如下图(有点粗糙 见谅)
代码如下: (代码里的keyinput就是一个读取输入的类 换成scanner就行 我只是keyinput用习惯了)
进程类
进程类
import link_about.KeyInput;
public class Process {
public int pid; //进程id
public int Cpu_com; //cpu指令条数
public int Cpu_io; //io指令条数
public int state_flag; //状态标志
public int io_wating; //io指令中需要等待的条数
public int io_wating_f;
boolean io_flag=false;
public Process(){ }
public void init(int no){
this.pid=no;
/* System.out.println("请输入指令总数");
total=KeyInput.readInt();*/
System.out.println("请输入cpu&io指令的值");
System.out.println("请输入cpu指令条数");
Cpu_com=KeyInput.readInt();
System.out.println("请输入io指令条数");
Cpu_io=KeyInput.readInt();
io_wating=Cpu_io*4;
io_wating_f=Cpu_io*4;
state_flag=0;
}
public String getState(){
switch (state_flag){
case 0:return "READY";
case 1:return "WAITING";
case 2:return "RUN:cup";
case 3:return "RUN:io";
case 4:return "DONE";
}
return null;
}
public boolean isRun(){
if(state_flag==2) return true;
return false;
}
public boolean isDone(){
if(state_flag==4) return true;
return false;
}
public boolean isReady(){
if(state_flag==0) return true;
return false;
}
public boolean isWaiting(){
if(state_flag==1) return true;
return false;
}
public boolean isRunning_io(){
if(state_flag==3) return true;
return false;
}
public void run(){
switch (state_flag){
case 0:
cpu_running();
break;
case 1:
break;
case 2:
cpu_running();
break;
case 3:
break;
case 4:return ;
}
}
private void cpu_running(){
if(Cpu_com>0){
state_flag=2;
Cpu_com--;
}
else cpu_running_io();
}
private void cpu_running_io(){
// if(this.isWaiting()) cpu_waiting();
if(Cpu_io>0) {
Cpu_io--;
state_flag=3;
}
else if(io_wating<=0) state_flag=4;
}
}
主类
import java.util.Stack;
//先来先服务
public class Main {
private static int time=0;//运行时间
static Stack<Process> stack_rdy=new Stack();//就绪栈
static Stack<Process> stack_run=new Stack();//运行栈
static Stack<Process> stack_waiting=new Stack();//等待栈
static Stack<Process> stack=new Stack<>();
// boolean end=false;
public static void main(String[] args) {
Process[] p=new Process[6];
for(int i=0;i<6;i++){
p[i]=new Process();
p[i].init(i);
}
Cpu cpu=new Cpu();
for(int i=5;i>=0;i--){
stack_rdy.push(p[i]);
}
System.out.println("Time PID:0 PID:1 PID:2 PID:3 PID:4 PID:5 CPU");
while(true){
time++;
while(!stack_waiting.isEmpty()){//对执行io指令的进程的管理
io_mangeer(stack_waiting.pop());
}
while(!stack.isEmpty()){
stack_waiting.push(stack.pop());
}
if(stack_run.isEmpty()&&!stack_rdy.isEmpty()) stack_run.push(stack_rdy.pop());
if(!stack_run.isEmpty()) manager(stack_run.pop());
System.out.println(time+" "+p[0].getState()+" "+p[1].getState()+" "+p[2].getState()+" "
+p[3].getState()+" "+p[4].getState()+" "+p[5].getState()+" "+cpu.runtime );
if(stack_rdy.isEmpty()&&stack_waiting.isEmpty()&&stack_run.isEmpty())
break;
}
}
public static void manager(Process px){
px.run();
if(px.isDone()) return;
if(px.isRun()) stack_run.push(px);
if(px.isRunning_io()) {
stack_waiting.push(px);
}
}
public static void io_mangeer(Process px){
if(px.io_wating<=0) {
px.state_flag=4;
return;
}
if(px.state_flag==3){
px.io_wating--;
px.state_flag=1;
stack.push(px);
return;
}
if(px.state_flag==1){
if(px.io_wating%4==0){
px.state_flag=0;
stack_rdy.push(px);
}
else {
// System.out.println("2332323");
px.io_wating--;
stack.push(px);
}
}
}
}