操作系统实验——基于Java的模拟操作系统进程切换(简易版)

实验任务

创建一个进程,给出工作量,每个进程所占的时间片大小为20个单位,实现就绪状态到执行状态之间的转化。如果一个进程在执行,点击其I/O请求即可产生阻塞,实现了等待一个事件的状态转移。阻塞状态到就绪状态需要事件发生,本程序为了简化,过40个时间单位自动解锁。本程序可以在VC、或其他程序设计语言中实现,容易使用时钟控件。在控制台模式下,该方式不是非常合适。

开始实验

一、 实验目的:

通过实验进一步了解进程状态之间的转换和进程控制等相关操作,通过实验的方法模拟进程在操作系统中是如何进行切换的,并掌握进程的数据结构;

二、 实验内容:

  1. 模拟进程PCB块,包括进程信息(id,名称,所需时间片,优先级,当前状态等)
  2. 建立三个队列(执行队列、就绪队列、等待队列) 在此我选用Java中的集合类ArrayList来实现。
  3. 根据用户输入进行系统交互和进程转换
  4. 用do-while语句和switch语句实现用户输入
  5. 要实现的功能:
  1. 新建进程(输入进程号、时间片)
  2. 将进程变为就绪状态 就绪
  3. 将进程变为等待状态 阻塞
  4. 将进行变为执行状态 执行
  5. 进程执行一次消耗5个时间片,执行完后自动变为就绪状态等待下一次执行
  6. 不能使除就绪状态的进程变为等待状态
  7. 进程在三个队列中只能存在一个
  8. 有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;
	}
	
}
  • 12
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
流程图,代码,截图三、程序源代码: #include"stdlib.h" #include"stdio.h" #include"string.h" /********** globle structure and viable ******/ struct PCB { int P_Id; //PCB的ID号 char P_Name[10]; //PCB的名称 char P_State[10]; //PCB状态 int P_Runtime; //PCB的所需要的运行时间 int P_Requiry; //PCB所需要的资源要求 struct PCB * next ; //PCB块的下一个指针 } ; struct PCB * Create_state; //创建状态 struct PCB * Run_state; //运行状态 struct PCB * Ready_state; //就绪状态 struct PCB * Block_state; //阻塞状态 struct PCB * Exit_state; //退出状态 int signal4=0; //标示进程4的完成状态 int signal5=0; //标示进程5的完成状态 void InsertQueue(struct PCB **head,struct PCB *node) /* insert node function */ { struct PCB * p,*q; node->next=NULL; if(*head==NULL) //如果队列为空 { *head=node; } Else //队列不空 { p=*head; q=p->next; while(q!=NULL) //找到最后的元素位置 { p=q; q=q->next; } p->next=node; //将节点插入队列 } } void DeleteQueue(struct PCB **head,struct PCB *node) //撤销进程,从队列中删除元素 { struct PCB *p,*q; q=*head; if(*head==NULL||node==NULL) //如果队列为空,返回 return ; if(*head==node) //如果要删除的元素是队首元素 { *head=(*head)->next; return; } Else //如果不是队列的首元素 { while(q->next!=p&&q->next!=NULL) q=q->next; q=p->next; p->next=NULL; } } void Display_Process(struct PCB * node) //打印进程状态的元素函数 { printf("\n\nthis process Id is : %d \n",node->P_Id); printf("this process name is : %s \n",node->P_Name); printf("this process state is : on %s \n ",node->P_State); printf("this process Runtime is : %d \n",node->P_Runtime); if(node->P_Requiry) printf("this process resource is ready \n"); else printf("this process resource is not ready ! \n"); } void DispatchToBlock(struct PCB *node) // /* dispatch to block function*/ { //调度到阻塞状态的函数 //struct PCB *p=(struct PCB *)malloc(sizeof(struct PCB)); if(!node->P_Requiry) //如果所需要的资源没有满足则,调度到阻塞状态 { strcpy(node->P_State,"block"); InsertQueue(&Block_state,node); //插入到阻塞队列 Display_Process(node); } } void DispatchToReady(struct PCB *node) // dispatch to ready state { //调度到就绪状态的函数 if(node->P_Requiry) //如果所需的资源满足,则调度 { strcpy(node->P_State,"Ready"); InsertQueue(&Ready_state,node); Display_Process(node); } } void DispatchBlockToReady() //dispatch the process to readyqueue { //从阻塞状态调度到就绪状态函数 struct PCB*p,*q; q=Block_state; while(q!=NULL) //如果阻塞状态队列不空 { p=q; q=q->next; if(signal4&&p->P_Id==4) //如果所需要的资源满足 { DeleteQueue(&Block_state,p); strcpy(p->P_State,"ready"); InsertQueue(&Ready_state,p); printf("process4 will be in the state of ready!\n"); Display_Process(p); } if(signal5&&p->P_Id==5) { DeleteQueue(&Block_state,p); strcpy(p->P_State,"ready"); InsertQueue(&Ready_state,p); printf("process5 will be in the state of ready!\n"); Display_Process(p); } } } void Create_Process() //创建进程函数 { int i; struct PCB *p; char name[10]; strcpy(name,"process"); for(i=1;iP_Id=i; name[7]=i+'0'; name[8]='\0'; strcpy(p->P_Name,name); strcpy(p->P_State,"create"); p->P_Runtime=1; //所需要的时间片为1 p->P_Requiry=0; Display_Process(p); sleep(4); printf(" \n process%d will be in the state of Block, waiting the resource ready \n\n",i); DispatchToBlock(p); //同时调度到阻塞队列 } for(i=3;iP_Id=i; name[7]=i+'0'; name[8]='\0'; strcpy(p->P_Name,name); strcpy(p->P_State,"create"); p->P_Requiry=1; if(i==6) //在这里个进程6所需要的时间片为2 p->P_Runtime=2; else p->P_Runtime=1; Display_Process(p); sleep(4); printf(" \n process%d will be in the state of Ready, waiting to run \n\n",i); DispatchToReady(p); } } void display(struct PCB **head) //打印各个状态队列里进程数目 { struct PCB *p,*q; p=*head; while(p!=NULL) { sleep(2); //printf("\n\n///////////////////////////////////\n"); printf("\n\nthis process Id is : %d \n",p->P_Id); printf("this process name is : %s \n",p->P_Name); printf("this process state is : on %s \n ",p->P_State); printf("this process Runtime is : %d \n",p->P_Runtime); if(p->P_Requiry) printf("this process resource is ready \n"); else printf("this process resource is not ready ! \n"); p=p->next; } } void Process_Run() //进程运行函数 { struct PCB *p,*q; p=Ready_state; q=p; while(p!=NULL) //就绪队列不空则继续执行 { if(p->P_RuntimeP_State,"running"); Display_Process(p); p->P_Runtime=p->P_Runtime-1; sleep(4); if(p->P_Runtime>0) //没有完成,则进入就绪队列 { printf("this process is not finished,will be dispatch to the ready queue!!\n"); DeleteQueue(&Ready_state,p); strcpy(p->P_State,"ready"); InsertQueue(&Ready_state,p); Display_Process(p); } Else //执行完成,则跳出,并发送相应的信息 { printf("\n\nProcess%d is finished and will be in the state of exit!\n\n",p->P_Id); if(p->P_Id==4) signal4=1; if(p->P_Id==5) signal5=1; } if(signal4||signal5) DispatchBlockToReady(); //如果资源满足,则将进程调度到就绪队列 q=q->next; p=q; } if(q==NULL) printf("\nthere is no process ready!\n STOP Machine!!!\n"); } int main(int argc,char * argv[]) //主函数 { int i; char c='c'; //界面 printf("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \n"); printf("...................................Ding Hai bo\n"); printf("......Press s to start the process.......\n"); scanf("%c",&c); while(1) { if(c=='s')break; scanf("%c",&c); } Create_Process(); //调用创建进程函数 printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); printf("\n>>>>>>> Display the Ready queue >>>>>>>>>>>>>>>\n"); sleep(5); display(&Ready_state); ////////////////显示就绪队列里的进程 printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"); printf("\n>>>>>>>> Display the Block queue >>>>>>>>>>>>\n"); sleep(5); //显示阻塞队列函数 display(&Block_state); ///////////////////// printf("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n\n"); printf("\n>>>>>>>> Now the process start to run >>>>>>>>>>>\n"); sleep(5); Process_Run(); //调用进程运行函数 } 都有

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值