操作系统实验:单处理器系统的进程调度(学习笔记)

题目要求

使用Java进行编程,模拟单处理器系统中的进程调度,实现时间片轮转、优先数、最短进程优先和最短剩余时间优先四种调度算法,并通过图形界面动态显示结果。

输入要求

通过鼠标触发用户界面可操作的JavaFX控件进行输入。
用户界面的可操作控件分别是一个下拉框和两个按钮。下拉框里展示了程序可以执行的调度算法,分别是“时间片轮转”、“优先数”、“最短进程优先”和“最短剩余时间优先”这四种调度算法。两个按钮中的一个是“确定/更改”按钮,用于选择所要执行的调度算法;另一个是“运行/停止”按钮,用于开始或关闭执行进程调度。

输出要求

使用JavaFX的文本展示控件来输出运行详情,包含三块输出区域,分别用于输出当前就绪态进程队列信息、处于运行态的进程和处于终止态的进程表。

编程平台

Eclipse 4.8.0 控制台

实验成果

初始界面

确定调度算法

开始调度



代码实现

各程序模块之间的层次 (调用)关系

用户界面变量预定义

// 初始化调度方法列表
private List<String> scheduingMethodList = Arrays.asList("时间片轮转", "优先数", "最短进程优先", "最短剩余时间优先");

ComboBox<String> comboBox; // 下拉框

Button selecteOrChange;    // 调度方法确定或更改按钮
Button runOrStop;          // 调度方法运行或暂停按钮

TextArea readyList; // 就绪态队列展示区
TextArea runList;   // 运行态队列展示区

// 完成态进程的PCB数据
public static List<PCB> PCBFinishList = new ArrayList<PCB>(); 

TableView<PCB> finishList; // 终止态进程表展示区
ObservableList<PCB> fList; // 终止态进程表展示区数据源

// 判断当前是否正在调度,便于中止调度
private static boolean scheduling = false;

进程控制块定义

public class PCB {
	// 设置进程控制块的数量上限为7
	private static final int MAX_PCB_NUM = 7;
   // 记录当前还能申请的进程控制块数量
	private static int remainingPCB = MAX_PCB_NUM; 
	// 定义进程控制块结构
	private int name;        // 进程标识符
	private String status;   // 进程状态
	private int originalPri; // 原始进程优先数
	private int pri;         // 进程优先数
	private int totalTime;   // 所需处理时间
	private int remainTime;  // 剩余处理时间
	
	public static boolean hasPCB() { // 判断是否有空余的进程控制块
		if(remainingPCB > 0) {
			return true;
		}
		return false;
	}

	public static PCB createPCB() { // 创建新的进程控制块
		PCB pcb = new PCB();
		--remainingPCB;
		return pcb;
	}
	
	public static void hadPCBFinished() { // 出现一个空余的进程控制块
		++remainingPCB;
	}
	
	@Override
	public String toString() { // 重写输出形式
		String nameSpace = "\t";
		String priSpace = "\t";
		if(name < 10) {
			nameSpace = "\t\t";
		}
		if(pri < 10) {
			priSpace = "\t\t";
		}
		return "标识符:" + name + nameSpace
				+ "状态:" + status + "\n"
				+ "优先数:" + pri + priSpace
				+ "所需处理时间:" + totalTime + "\n"
				+ "剩余处理时间:" + remainTime;
	}
	
}

进程定义

public class Process {
	
	private static ArrayList<Integer> existedName = new ArrayList<Integer>(); // 记录已生成的标识符
	
	public static PCB createProcess() { // 随机生成一个进程控制块
		PCB pcb = null;
		if(PCB.hasPCB()) {
			pcb = PCB.createPCB(); // 申请一个进程控制块
			pcb.setName(generateUniqueName());
		    pcb.setStatus("就绪");
		    pcb.setOriginalPri((int) (Math.random() * 15 + 1));
		    pcb.setPri(pcb.getOriginalPri());
		    pcb.setTotalTime((int) (Math.random() * 10 + 1));
		    pcb.setRemainTime(pcb.getTotalTime());
		}
		return pcb;
	}
	
	public static void existFinsihed() { // 出现一个进程为终止态
		PCB.hadPCBFinished();
	}
	
	public static String outputPCB(PCB pcb) { // 输出申请到的进程控制块的内容
		if(pcb != null) {
			return pcb.toString();
		}
		return "";
	}
	
	private static int generateUniqueName() { // 随机生成标识符
		int name = (int) (Math.random() * 100 + 1);
		while(isExisted(name)) {
			name = (int) (Math.random() * 100 + 1);
		}
		return name;
	}
	
	private static boolean isExisted(int name){ // 判断随机生成的标识符是否已存在
		for(int i = 0; i < existedName.size(); ++i) {
			if(existedName.get(i) == name) {
				return true;
			}
		}
		existedName.add(name);
		return false;
	}
	
}

进程管理模块

public class ManageProcess {

	private static ArrayList<PCB> readyProcessList = new ArrayList<PCB>(); // 记录已生成的就绪态进程队列

	public static boolean hasReadyProcess() { // 判断是否已有就绪态队列
		if(readyProcessList.size() == 0) {
			return false;
		}
		return true;
	}
	
	public static void originateReadyProcessList() { // 初始化就绪态进程队列
		while(readyProcessList.size() < 4) {
			createReadyProcess();
		}
	}
	
	public static String showReadyProcessList() { // 展示当前的就绪态进程队列
		String show = "";
		for(int i = 0; i < readyProcessList.size(); ++i) {
			if(show != "") {
				show += "\n-----------------------------------------------\n";
			}
			show += Process.outputPCB(readyProcessList.get(i));
		}
		return show;
	}
	
	public static void createReadyProcess() { // 生成一个就绪态进程
		PCB pcb = Process.createProcess();
		if(pcb != null) {
			addReadyProcess(pcb);
		}
	}
	
	public static PCB getReadyProcess(int index) { // 获得一个就绪态进程
		if(index < readyProcessList.size()) {
			return readyProcessList.get(index);
		}
		return null;
	}
	
	public static void addReadyProcess(PCB pcb) { // 添加一个就绪态进程
		readyProcessList.add(pcb);
	}
	
	public static void removeReadyProcess(int index) { // 删除一个就绪态进程
		readyProcessList.remove(index);
	}
	
	public static int getReadyProcessNumber() { // 获得就绪态进程队列的数量
		return readyProcessList.size();
	}
	
	public static void sortReadyProcessNumber(String schedulingMethod) { // 对就绪态进程队列进行排序
		if(schedulingMethod == "优先数") {
			Collections.sort(readyProcessList, new Comparator<PCB>() {
				@Override
				public int compare(PCB a, PCB b)
				{	
					if(a.getPri() < b.getPri()) return 1;
					else if(a.getPri() > b.getPri()) return -1;
					else return 0;
				}			
			});
		}else if(schedulingMethod == "最短进程") {
			Collections.sort(readyProcessList, new Comparator<PCB>() {
				@Override
				public int compare(PCB a, PCB b)
				{	
					if(a.getTotalTime() < b.getTotalTime()) return -1;
					else if(a.getTotalTime() > b.getTotalTime()) return 1;
					else return 0;
				}			
			});
		}
	}
	
	public static int getMinReaminTimeProcess() { // 获得剩余处理时间最短的就绪态进程的下标
		int index = -1;
		if(readyProcessList.size() != 0) {
			index = 0;
			for(int i = 1; i < readyProcessList.size(); ++i) {
				if(readyProcessList.get(index).getRemainTime() > 
				readyProcessList.get(i).getRemainTime()) {
					index = i;
				}
			}
		}
		return index;
	}
	
	public static void resetReaminTime() { // 用于调度突然中止时重置就绪态进程的剩余处理时间为所需处理时间
		for(int i = 0; i < readyProcessList.size(); ++i) {
	readyProcessList.get(i).setRemainTime(readyProcessList.get(i).getTotalTime());
		}
	}
}

进程调度模块

public class Schedule {
	
	private static final int timeSlicing = 3; // 默认时间片
	private static int remainTimeSlicing = timeSlicing; // 剩余时间片
	private static PCB runProcess = null; // 运行态进程
	private static int index = 0; // 就绪态进程下标(用于最短剩余时间调度)
	
	public static boolean startSchedule(String schedulingMethod) { // 判断能否开始调度
		
		boolean allow = false;
		if(countProcess() > 0) { // 存在进程
			if(schedulingMethod == "时间片轮转") {
				timeSlicingRR();
			}else if(schedulingMethod == "优先数") {
				priority();
			}else if(schedulingMethod == "最短进程优先") {
				SPN();
			}else if(schedulingMethod == "最短剩余时间优先") {
				SRT();
			}
			allow = true;
		}else {
			runProcess = null;
			remainTimeSlicing = timeSlicing;
		}
		return allow;
		
	}
	
	public static void stopSchedule() { // 中止调度
		if(runProcess != null) {
			runProcess.setStatus("就绪");
			runProcess.setRemainTime(runProcess.getRemainTime() + 1);
			ManageProcess.addReadyProcess(runProcess);
		}
		ManageProcess.resetReaminTime();
		runProcess = null;
		remainTimeSlicing = timeSlicing;
	}
	
	// 四种调度算法实现代码

	public static String showRunProcess(String schedulingMethod) { // 展示运行态进程
		String show = "";
		if(schedulingMethod == "时间片轮转") {
			if(remainTimeSlicing != timeSlicing + 1) {
				if(runProcess != null) {
					show = Process.outputPCB(runProcess);
					show += "\n剩余时间片:" + remainTimeSlicing; 
				}
			}
			--remainTimeSlicing;
		}else if(schedulingMethod == "优先数") {
			if(remainTimeSlicing == 3) {
				show = "正在按优先数对就绪态进程队列进行排序……";
			}else if(remainTimeSlicing == 2) {
				show = "就绪态进程队列已按优先数排序!";
			}else {
				if(remainTimeSlicing != timeSlicing + 1) {
					if(runProcess != null) {
						show = Process.outputPCB(runProcess);
						show += "\n剩余时间片:" + remainTimeSlicing; 
					}
				}
			}
			--remainTimeSlicing;
		}else if(schedulingMethod == "最短进程优先") {
			if(remainTimeSlicing == 3) {
				show = "正在按最短运行时间对就绪态进程队列进行\n排序……";
			}else if(remainTimeSlicing == 2) {
				show = "就绪态进程队列已按最短运行时间排序!";
			}else {
				if(runProcess != null) {
					show = Process.outputPCB(runProcess);
				}
			}
			--remainTimeSlicing;
		}else if(schedulingMethod == "最短剩余时间优先") {
			if(remainTimeSlicing == 3) {
				show = "正在从就绪态进程队列中挑选剩余时间最短的\n进程……";
			}else {
				if(remainTimeSlicing != timeSlicing + 1) {
					if(runProcess != null) {
						show = Process.outputPCB(runProcess);
					}
					if(remainTimeSlicing == timeSlicing + 3) {
						show += "\n(此时该进程被标识符为" + ManageProcess.getReadyProcess(index).getName() + "的进程抢占!)";
					}
				}
			}
			--remainTimeSlicing;
		}
		return show;
	}
	
	private static int countProcess() { // 计算进程数量
		int remainProcess = ManageProcess.getReadyProcessNumber();
		if(runProcess != null) {
			++remainProcess;
		}
		return remainProcess;
	}
	
	private static void addNewReadyProcess() { // 随机添加新进程
		if(runProcess.getRemainTime() == 5) {
			if(countProcess() < 7) {
				ManageProcess.createReadyProcess();
			}
		}
	}
	
}

进程调度控制

private void SchedulingProcess(String schedulingMethod) { // 控制进程调度
	scheduling = true;
	Timer timer = new Timer();
	TimerTask task = new TimerTask() {
		public void run() {
			try {
				while(Schedule.startSchedule(schedulingMethod) && scheduling) {
					readyList.setText(ManageProcess.showReadyProcessList());
					runList.setText(Schedule.showRunProcess(schedulingMethod));
					if(runList.getText().isEmpty()) {
						fList = FXCollections.observableArrayList(PCBFinishList);
						finishList.setItems(fList);
					}
					Thread.sleep(1000);
				}
				if(scheduling == false) {
					Schedule.stopSchedule();
					readyList.setText(ManageProcess.showReadyProcessList());
					runList.clear();
				}else {
					readyList.setText("注意:本程序最多同时存在7个非终止态进程!");
					runOrStop.setDisable(true);
					selecteOrChange.setDisable(false);
					comboBox.setDisable(false);
				}
				timer.cancel();
				timer.purge();
			}catch(Exception ex) {
				Alert error = new Alert(AlertType.ERROR);
				error.setHeaderText("调度出错");
				error.setContentText("具体错误:" + ex.toString());
				error.showAndWait();
			}

		}
	};
	timer.schedule(task, 100);
}

时间片轮转调度

private static void timeSlicingRR() { // 时间片轮转调度
	if(remainTimeSlicing == timeSlicing) {
		runProcess = ManageProcess.getReadyProcess(0);
		runProcess.setStatus("运行");
		ManageProcess.removeReadyProcess(0);
	}else {
		if(remainTimeSlicing >= 0) {
			if(runProcess.getRemainTime() > 0) {
				addNewReadyProcess(); // 随机添加新进程
				runProcess.setRemainTime(runProcess.getRemainTime() - 1);
				if(runProcess.getRemainTime() == 0) {
					runProcess.setStatus("终止");
					UserGUI.PCBFinishList.add(runProcess); 
					Process.existFinsihed();
					remainTimeSlicing = 0;
				}
			}
		}else {
			if(runProcess.getRemainTime() > 0) {
				runProcess.setStatus("就绪");
				ManageProcess.addReadyProcess(runProcess);
			}
			remainTimeSlicing = timeSlicing + 1;
			runProcess = null;
		}
	}
}

优先数调度

private static void priority() { // 优先数调度
	if(remainTimeSlicing == 2) {
		ManageProcess.sortReadyProcessNumber("优先数");
	}else if(remainTimeSlicing == 1) {
		runProcess = ManageProcess.getReadyProcess(0);
		runProcess.setStatus("运行");
		ManageProcess.removeReadyProcess(0);
	}else if(remainTimeSlicing == 0) {
		addNewReadyProcess(); // 随机添加新进程
		if(runProcess.getPri() != 0) {
			runProcess.setPri(runProcess.getPri() - 1);
		}
		runProcess.setRemainTime(runProcess.getRemainTime() - 1);
	}else {
		if(remainTimeSlicing != timeSlicing) {
			if(runProcess.getRemainTime() == 0) {
				runProcess.setStatus("终止");
				UserGUI.PCBFinishList.add(runProcess);
				Process.existFinsihed();
			}else {
				runProcess.setStatus("就绪");
				ManageProcess.addReadyProcess(runProcess);
			}
			remainTimeSlicing = timeSlicing + 1;
			runProcess = null;
		}
	}
}

最短进程优先调度

private static void SPN() { // 最短进程优先调度
	if(remainTimeSlicing == 2) {
		ManageProcess.sortReadyProcessNumber("最短进程");
	}else if(remainTimeSlicing == 1) {
		runProcess = ManageProcess.getReadyProcess(0);
		runProcess.setStatus("运行");
		ManageProcess.removeReadyProcess(0);
	}else if(remainTimeSlicing == timeSlicing + 1) {
		runProcess = null;
	}else {
		if(remainTimeSlicing != timeSlicing) {
			addNewReadyProcess(); // 随机添加新进程
			runProcess.setRemainTime(runProcess.getRemainTime() - 1);
			if(runProcess.getRemainTime() == 0) {
				runProcess.setStatus("终止");
				UserGUI.PCBFinishList.add(runProcess);
				Process.existFinsihed();
				remainTimeSlicing = timeSlicing + 2;
			}
		}
	}
}

最短剩余时间优先调度

private static void SRT() { // 最短剩余时间优先调度
	if(remainTimeSlicing == 2) {
		index = ManageProcess.getMinReaminTimeProcess();
		runProcess = ManageProcess.getReadyProcess(index);
		runProcess.setStatus("运行");
		ManageProcess.removeReadyProcess(index);
	}else if(remainTimeSlicing == timeSlicing + 2){
		PCB pcb = runProcess;
		runProcess = ManageProcess.getReadyProcess(index);
		runProcess.setStatus("运行");
		ManageProcess.removeReadyProcess(index);
		pcb.setStatus("就绪");
		ManageProcess.addReadyProcess(pcb);
		remainTimeSlicing = 2;
	}else if(remainTimeSlicing == timeSlicing + 1){
		remainTimeSlicing = timeSlicing + 1;
		runProcess = null;
	}else {
		if(remainTimeSlicing != timeSlicing) {
			index = ManageProcess.getMinReaminTimeProcess();
			if(index == -1) {
				runProcess.setRemainTime(runProcess.getRemainTime() - 1);
				if(runProcess.getRemainTime() == 0) {
					runProcess.setStatus("终止");
					UserGUI.PCBFinishList.add(runProcess);
					Process.existFinsihed();
					remainTimeSlicing = timeSlicing + 2;
				}
			}else {
				if(runProcess.getRemainTime() <= ManageProcess.getReadyProcess(index).getRemainTime()) {
					addNewReadyProcess(); // 随机添加新进程
					runProcess.setRemainTime(runProcess.getRemainTime() - 1);
					if(runProcess.getRemainTime() == 0) {
						runProcess.setStatus("终止");
						UserGUI.PCBFinishList.add(runProcess);
						Process.existFinsihed();
						remainTimeSlicing = timeSlicing + 2;
					}
				}else {
					remainTimeSlicing = timeSlicing + 3;
				}
			}
		}
	}
}

如果文章内容出错或者您有更好的解决方法,欢迎到评论区指正和讨论!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值