实验任务
创建一个进程,给出工作量,每个进程所占的时间片大小为20个单位,实现就绪状态到执行状态之间的转化。如果一个进程在执行,点击其I/O请求即可产生阻塞,实现了等待一个事件的状态转移。阻塞状态到就绪状态需要事件发生,本程序为了简化,过40个时间单位自动解锁。本程序可以在VC、或其他程序设计语言中实现,容易使用时钟控件。在控制台模式下,该方式不是非常合适。
开始实验
一、 实验目的:
通过实验进一步了解进程状态之间的转换和进程控制等相关操作,通过实验的方法模拟进程在操作系统中是如何进行切换的,并掌握进程的数据结构;
二、 实验内容:
- 模拟进程PCB块,包括进程信息(id,名称,所需时间片,优先级,当前状态等)
- 建立三个队列(执行队列、就绪队列、等待队列) 在此我选用Java中的集合类ArrayList来实现。
- 根据用户输入进行系统交互和进程转换
- 用do-while语句和switch语句实现用户输入
- 要实现的功能:
- 新建进程(输入进程号、时间片)
- 将进程变为就绪状态 就绪
- 将进程变为等待状态 阻塞
- 将进行变为执行状态 执行
- 进程执行一次消耗5个时间片,执行完后自动变为就绪状态等待下一次执行
- 不能使除就绪状态的进程变为等待状态
- 进程在三个队列中只能存在一个
- 有IO请求的时候停止当前运行进程
三、 实验步骤:
1. 创建一个进程类 包含的信息有 id、名称、所需时间片、优先级、当前状态;及其获取这些信息的方法
2. 系统类,定义了主函数main()
和某些工具方法及方法函数
图:系统类定义的队列
图:系统类中的调用关系
图:系统类提供的相关工具方法及函数
3. 详解运行方法 runProcess()
是如何实现的:
首先分析运行进程所需要的条件:进程状态为就绪或者运行而且时间片不小于0
可以用两种分支来进行运行程序:
1.进程为就绪状态,将进程从就绪队列中删除,并添加到运行队列中,修改程序状态和时间片
2.进程为运行状态,修改时间片,并添加到运行队列尾等待下一次运行
相关源码:
//运行一个进程
private static void runProcess() {
// TODO Auto-generated method stub
Process process;
if (!Dlists.isEmpty()) {
process = Dlists.get(0);
if (process.getState()==2) {
System.out.println("直接");
for (int i = 5; i >= 1; i--) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("进程"+process.getPid()+"正在运行");
process.setPtime(process.getPtime()-1);
}
System.out.println("进程"+process.getPid()+"剩余运行时间:"+process.getPtime()+"\t 进程结束运行");
readProcess(process.getPid());
}else {
System.out.println("当前队列进程无法运行不为2");
readProcess(process.getPid());
}
}
else if (!Rlists.isEmpty()) {
System.out.println("间接");
process = Rlists.get(0);
if ((process.getState()==1&&(process.getPtime()>0))) {
process.setState(2);
Rlists.remove(0);
Dlists.add(process);
for (int i = 5; i >= 1; i--) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("进程"+process.getPid()+"正在运行");
process.setPtime(process.getPtime()-1);
}
System.out.println("进程"+process.getPid()+"剩余运行时间:"+process.getPtime()+"\t 进程结束运行");
readProcess(process.getPid());
}else if (process.getState()==1) {
Rlists.remove(0);
System.out.println("进程"+process.getPid()+"时间片剩余不足,已销毁");
}else if (process.getState()!=1){
System.out.println("当前队列进程无法运行不为1");
System.out.println(process.getState());
}else {
System.out.println("当前队列进程无法运行");
System.out.println(process.getState());
System.out.println(process.getPtime());
}
}else {
System.out.println("运行队列为空,请添加运行");
}
}
四、 实验结果:
1. 新建进程信息
2. 将进程添加至就绪状态
3. 查看当前队列信息
4. 运行进程
5. IO中断
6. 结束
(程序结束的时候,想了一下,还是用-1作为结束比较好)
<--------------------------------------------------------------------------------------------------->
此代码为榴莲男孩原创,转载引用请标明出处
代码中存在一部分错误,请自行修改,如有问题,欢迎指出参与讨论
from----仲恺农业工程学院
<--------------------------------------------------------------------------------------------------->
实验源码
test1 系统类
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.util.Scanner;
public class test1 {
static ArrayList<Process> Rlists = new ArrayList<Process>();//就绪队列
static ArrayList<Process> Wlists = new ArrayList<Process>();//等待队列
static ArrayList<Process> Dlists = new ArrayList<Process>();//运行队列
public static void main(String[] args) {
Scanner inputScanner = new Scanner(System.in);
Wlists.add(new Process(0, 20));
Wlists.add(new Process(20, 20));
Wlists.add(new Process(2, 20));
Wlists.add(new Process(1, 15));
do{
prints();
int input;
String string ="";
if(inputScanner.hasNext())
string = inputScanner.nextLine();
else {
inputScanner.nextLine();
string = inputScanner.nextLine();
}
input = Integer.valueOf(string);
if(string.equals("-1")) {
System.out.println("程序结束");
break;
}
System.out.println("您的输入为:"+input);
switch (input) {
case 1:
newProcess();
break;
case 2:
RdyProcess();
System.out.println(11);
break;
case 3:
IOrequest();
break;
case 4:
DoProcess();
break;
case 5:
queryRProcess();
break;
case 6:
queryWProcess();
break;
default:
System.out.println("您的输入有误,请重新输入1-6的数据,0为结束");
break;
}
}while (true);
inputScanner.close();
System.out.println("程序结束");
}
private static void IOrequest() {
// TODO Auto-generated method stub
if (Dlists.isEmpty()) {
System.out.println("当前运行队列没有进程");
}else {
waitProcess(Dlists.get(0).getPid());
}
}
private static void newProcess() {
// TODO Auto-generated method stub
System.out.println("新建一个进程");
Scanner scanner = new Scanner(System.in);
System.out.print("请输入进程号:");
int id = Integer.valueOf(scanner.nextLine());
System.out.print("请输入运行时间");
int time = Integer.valueOf(scanner.nextLine());
Wlists.add(new Process(id, time));
System.out.println("创建成功");
}
private static void RdyProcess() {
// TODO Auto-generated method stub
System.out.print("请输入你要就绪的进程号:");
Scanner scanner = new Scanner(System.in);
int id = scanner.nextInt();
readProcess(id);
System.out.println("进程已就绪");
}
private static void DoProcess() {
// TODO Auto-generated method stub
runProcess();
}
/*************函数方法************************************/
//查看等待队列
private static void queryWProcess() {
// TODO Auto-generated method stub
System.out.print("等待队列中的进程:");
for (Process processes : Wlists) {
System.out.print(processes.getPid()+"->");
}
System.out.println("null");
}
//查看就绪队列
private static void queryRProcess() {
// TODO Auto-generated method stub
System.out.print("就绪队列中的进程:");
for (Process processes : Rlists) {
System.out.print(processes.getPid()+"->");
}
System.out.println("null");
}
//查看运行队列
private static void queryDProcess() {
// TODO Auto-generated method stub
System.out.print("运行队列中的进程:");
for (Process processes : Dlists) {
System.out.print(processes.getPid()+"->");
}
System.out.println("null");
}
//运行一个进程
private static void runProcess() {
// TODO Auto-generated method stub
Process process;
if (!Dlists.isEmpty()) {
process = Dlists.get(0);
if (process.getState()==2) {
System.out.println("直接");
for (int i = 5; i >= 1; i--) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("进程"+process.getPid()+"正在运行");
process.setPtime(process.getPtime()-1);
}
System.out.println("进程"+process.getPid()+"剩余运行时间:"+process.getPtime()+"\t 进程结束运行");
readProcess(process.getPid());
}else {
System.out.println("当前队列进程无法运行不为2");
readProcess(process.getPid());
}
}
else if (!Rlists.isEmpty()) {
System.out.println("间接");
process = Rlists.get(0);
if ((process.getState()==1&&(process.getPtime()>0))) {
process.setState(2);
Rlists.remove(0);
Dlists.add(process);
for (int i = 5; i >= 1; i--) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("进程"+process.getPid()+"正在运行");
process.setPtime(process.getPtime()-1);
}
System.out.println("进程"+process.getPid()+"剩余运行时间:"+process.getPtime()+"\t 进程结束运行");
readProcess(process.getPid());
}else if (process.getState()==1) {
Rlists.remove(0);
System.out.println("进程"+process.getPid()+"时间片剩余不足,已销毁");
}else if (process.getState()!=1){
System.out.println("当前队列进程无法运行不为1");
System.out.println(process.getState());
}else {
System.out.println("当前队列进程无法运行");
System.out.println(process.getState());
System.out.println(process.getPtime());
}
}else {
System.out.println("运行队列为空,请添加运行");
}
}
//将进程变为等待
private static void waitProcess(int id) {
// TODO Auto-generated method stub
if (getIndex(id, Dlists)!=-1) {
Wlists.add(Dlists.get(getIndex(id, Dlists)));
Dlists.get(getIndex(id, Dlists)).setState(0);//将进程设为等待状态|标记
Dlists.remove(getIndex(id, Dlists));
}else if (getIndex(id, Rlists)!=-1) {
Wlists.add(Rlists.get(getIndex(id, Rlists)));
Rlists.get(getIndex(id, Rlists)).setState(0);//将进程设为等待状态|标记
Rlists.remove(getIndex(id, Rlists));
}else if (getIndex(id, Wlists)!=-1) {
System.out.println("此进程已经在等待中");
}else {
System.out.println("不存在此进程");
}
}
//就绪一个进程
private static void readProcess(int id) {
// TODO Auto-generated method stub
if (getIndex(id, Dlists)!=-1) {
Rlists.add(Dlists.get(getIndex(id, Dlists)));
Dlists.get(getIndex(id, Dlists)).setState(1);//将进程设为就绪状态|标记
Dlists.remove(getIndex(id, Dlists));
}else if (getIndex(id, Wlists)!=-1) {
Rlists.add(Wlists.get(getIndex(id, Wlists)));
Wlists.get(getIndex(id, Wlists)).setState(1);//将进程设为就绪状态|标记
Wlists.remove(getIndex(id, Wlists));
}else if (getIndex(id, Rlists)!=-1) {
System.out.println("此进程已经在就绪中");
}else {
System.out.println("不存在此进程");
}
}
/*****************工具类******************************/
//打印提示语
public static void prints() {
System.out.println("请输入要进行的操作:\n"
+ "1:创建一个进程\t\t2:将一个进程变为就绪"
+ "\n3:此时有一个IO请求\t4:执行一个进程\n"
+ "5:查看当前就绪队列\t6:查看当前准备队列"
+"输入-1退出程序");
}
//集合的查询
private static int getIndex(int nub ,ArrayList<Process> process) {
int rs = -1;
for (Process process2 : process) {
if(process2.getPid() == nub)
rs = process.indexOf(process2);
}
return rs;
}
/*
char input;
prints();
Scanner inputScanner = new Scanner(System.in);
input = inputScanner.nextLine().charAt(0);
while (input != '0') {
System.out.println("您的输入为:"+input);
switch (input) {
case '1':
newProcess(Wlists);
break;
case '2':
readProcess(Rlists);
System.out.println(11);
break;
case '3':
waitProcess(Wlists);
break;
case '4':
runProcess(Rlists);
break;
case '5':
queryRProcess();
break;
case '6':
queryWProcess();
break;
default:
System.out.println("您的输入有误,请重新输入1-6的数据,0为结束");
prints();
break;
}
try {
input = inputScanner.nextLine().charAt(0);
} catch (Exception e) {
// TODO: handle exception
System.out.println("您的输入有误,请重新输入1");
prints();
input = inputScanner.nextLine().charAt(0);
continue;
}
}
System.out.println("程序结束");
*/
}
Process 进程类
public class Process {
private int pid;//进程编号
private int proiority = 0;//优先级
private String pname = null;//进程名
private int state = 0;//状态 0为等待 1为就绪 2为运行 3为死亡
private int ptime = 3;//时间片 都为3
public Process(int pid, int ptime) {
super();
this.pid = pid;
this.ptime = ptime;
}
public Process(int pid, String pname) {
super();
this.pid = pid;
this.pname = pname;
}
public Process(int pid, int proiority, String pname) {
super();
this.pid = pid;
this.proiority = proiority;
this.pname = pname;
}
public void Pready() {
if(this.state!=0) {
System.out.println(this.getPid()+this.getPname()+"进程无法就绪");
return;
}
this.setState(1);
System.out.println(this.getPid()+this.getPname()+"进程正在就绪");
}
public void Prun() {
if(this.state!=1) {
System.out.println(this.getPid()+this.getPname()+"进程未进入就绪状态");
return;
}
this.setState(2);
System.out.println(this.getPid()+this.getPname()+"进程正在运行");
}
public void Pdead() {
this.setState(3);
System.out.println(this.getPid()+this.getPname()+"进程已销毁");
}
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
public int getProiority() {
return proiority;
}
public void setProiority(int proiority) {
this.proiority = proiority;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public int getPtime() {
return ptime;
}
public void setPtime(int ptime) {
this.ptime = ptime;
}
}