1. 程式人生 > >【計算機作業系統】用java模擬非搶佔式(先來先到、短作業、高響應比),時間片輪轉排程演算法

【計算機作業系統】用java模擬非搶佔式(先來先到、短作業、高響應比),時間片輪轉排程演算法

. 首先,我來介紹一下該程式大致內容

  • 程式使用了ArrayList連結串列來模擬各程序佇列,並且結果會顯示出每個時刻的程序的執行資訊、最後的所有程序的執行結果和程序的執行順序。
  • ps:各個模擬程式是相互獨立,如果不需要的直接刪除即可。

現在介紹每個排程演算法的思想
非搶佔式先來先到:首先初始化變數,當後備佇列和就緒佇列都不為空時,按照達到時間順序執行,執行的每一時刻都要判斷是否有到達的程序,如果有,就插入到就緒佇列中,然後迴圈往復,直到後備佇列和就緒佇列都為空為止。這裡我們需要處理幾個特殊情況:
一:同時到達的多個程序,按照預設排序執行。
二:當就緒佇列無程序執行,這時後備佇列還有程序

public void FCFS(ArrayList<PCB> p) {
		if (!init(p))
			return;
		while (!(processPoolList.isEmpty() && processReadyList.isEmpty())) { // 程序的執行過程
			PCB process = processReadyList.get(0);
			process.setState("Running");

			informationProcess(process);// 當前程序資訊

			for (int i = process.getAllTime() - 1, j = 1; i >= 0; j++, i--) { // 程序執行階段
				process.setAllTime(i);// 所需要的cup的時間減減
				process.setCupTime(j);// 已佔cup的時間加加
				t++;// 模擬時間增加
				System.out.println(t + "\t\t" + process.getId() + "\t\t" + process.getAllTime() + "\t\t"
						+ process.getCupTime() + "\t\t" + process.getState());
				try {
					Thread.sleep(500); // 睡眠
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

				if (!processPoolList.isEmpty()) {// 找該時刻到達的程序
					insertProcess();
				}

				if (i == 1)
					process.setState("End");// 程序結束

			}
			System.out.println("程序" + process.getId() + "執行結束");

			result(process);
			sequence[flag++]=processReadyList.get(0).getId();
			processReadyList.remove(0); // 移除已經執行玩的程序

			if (processReadyList.isEmpty() && !processPoolList.isEmpty()) {// 如果就緒“佇列”為空,這找到下一個
				t = processPoolList.get(0).getProcessArrivalTime();
				insertProcess();
			}

		}
		show();// 顯示FCFS演算法的最終結果
	}

非搶佔式短作業:首先初始化變數,當後備佇列和就緒佇列都不為空時,判斷是否存在多個已到程序,若存在,按照服務時間短的優先執行,若不存在,按照達到時間順序執行,在執行程序的過程中,每一時刻都要判斷是否有到達的程序,如果有,就插入到就緒佇列中。然後重複上述操作,直到後備佇列和就緒佇列都為空為止。這裡我們需要處理幾個特殊情況:
一:同時到達的多個程序。按照短服務時間優先原則
二:當就緒佇列無程序執行,這時後備佇列還有程序

public void SJF(ArrayList<PCB> p) {
		if (!init(p))
			return;
		if (processReadyList.size() > 1) {// 處理同時達到的多個程序
			for (int i = 1; i < processReadyList.size(); i++) {// 找到中先到且時間最短的程序
				if (processReadyList.get(i).getProcessServiceTime() < processReadyList.get(i - 1)
						.getProcessServiceTime())
					index = i;
			}
		}
		while (!(processPoolList.isEmpty() && processReadyList.isEmpty())) { // 程序的執行過程
			PCB process = processReadyList.get(index);
			process.setState("Running");

			informationProcess(process);// 當前程序資訊

			for (int i = process.getAllTime() - 1, j = 1; i >= 0; j++, i--) { // 程序執行階段
				process.setAllTime(i);// 所需要的cup的時間減減
				process.setCupTime(j);// 已佔cup的時間加加
				t++;
				System.out.println(t + "\t\t" + process.getId() + "\t\t" + process.getAllTime() + "\t\t"
						+ process.getCupTime() + "\t\t" + process.getState());
				try {
					Thread.sleep(500); // 睡眠
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

				if (!processPoolList.isEmpty()) {// 找該時刻到達的程序
					insertProcess();
				}

				if (i == 1)
					process.setState("End");// 程序結束

			}
			System.out.println("程序" + process.getId() + "執行結束");

			result(process);
			sequence[flag++]=processReadyList.get(index).getId();
			processReadyList.remove(index); // 移除已經執行完的程序
			
			if (processReadyList.isEmpty() && !processPoolList.isEmpty()) {// 如果就緒“佇列”為空,這找到下一個
				t = processPoolList.get(0).getProcessArrivalTime();
				insertProcess();
			}

			if (processReadyList.size() > 1) { // 判斷就緒"佇列"中的程序數,如果大於1,則找到服務時間最短的程序
				index = 0;
				for (int j = 1; j < processReadyList.size(); j++) {
					if (processReadyList.get(index).getProcessServiceTime() > processReadyList.get(j)
							.getProcessServiceTime())
						index = j;
				}
			} else
				index = 0;
		}
		show();// 顯示JSF演算法的最終結果
	}

非搶佔式高響應比:首先初始化變數,當後備佇列和就緒佇列都不為空時,判斷是否存在多個已到程序,若存在,計算程序此時的優先順序,按照高優先順序先執行原則,若不存在,按照達到時間順序執行,在執行程序的過程中,每一時刻都要判斷是否有到達的程序,如果有,就插入到就緒佇列中。然後重複上述操作,直到後備佇列和就緒佇列都為空為止。這裡我們需要處理幾個特殊情況:
一:同時到達的多個程序。按照優先順序高優先原則,優先順序一樣,則按照短作業優先,若兩個都一樣,則按照到到達時間
二:當就緒佇列無程序執行,這時後備佇列還有程序

public void HRRN(ArrayList<PCB> p) {
		index = 0;
		if (!init(p))
			return;
		if (processReadyList.size() > 1) {// 處理同時達到的多個程序
			for (int i = 1; i < processReadyList.size(); i++) {// 找到中先到且時間最短的程序
				if (processReadyList.get(i).getProcessServiceTime() < processReadyList.get(i - 1)
						.getProcessServiceTime())
					index = i;
			}
		}
		while (!(processPoolList.isEmpty() && processReadyList.isEmpty())) { // 程序的執行過程
			PCB process = processReadyList.get(index);
			process.setState("Running");
			System.out.println("當前執行程序" + process.getId());
			System.out.println("當前時間\t\t程序ID\t\tAllTime\t\tcpuTime\t\tpriority\tState");
			System.out.print(t + "\t\t" + process.getId() + "\t\t" + process.getAllTime() + "\t\t"
					+ process.getCupTime() + "\t\t");
			System.out.printf("%.2f\t\t%s\n", process.getPriority(), process.getState());

			for (int i = process.getAllTime() - 1, j = 1; i >= 0; j++, i--) {
				process.setAllTime(i);// 所需要的cup的時間減減
				process.setCupTime(j);// 已佔cup的時間加加
				t++;
				System.out.print(t + "\t\t" + process.getId() + "\t\t" + process.getAllTime() + "\t\t"
						+ process.getCupTime() + "\t\t");
				System.out.printf("%.2f\t\t%s\n", process.getPriority(), process.getState());
				try {
					Thread.sleep(500); // 睡眠
				} catch (InterruptedException e) {
				}

				if (!processPoolList.isEmpty()) {// 找該時刻到達的程序
					insertProcess();
				}

				if (i == 1)
					process.setState("End");// 程序結束
			}
			System.out.println("程序" + process.getId() + "執行結束");

			result(process);
			sequence[flag++]=processReadyList.get(index).getId();
			processReadyList.remove(index); // 移除已經執行玩的程序
			if (processReadyList.isEmpty() && !processPoolList.isEmpty()) {// 如果就緒“佇列”為空,這找到下一個
				t = processPoolList.get(0).getProcessArrivalTime();
				insertProcess();
			}

			index = 0;
			if (processReadyList.size() > 1) {// 判斷就緒"佇列"的個數是否大於1,如果是,求出各程序優先順序,並找出優先順序最高的程序
				System.out.println("當前就緒對列中各程序的優先順序");
				for (int i = 0; i < processReadyList.size(); i++) {
					double temp = 1 + (t - processReadyList.get(i).getProcessArrivalTime())
							/ (double) processReadyList.get(i).getProcessServiceTime();
					System.out.print("程序" + processReadyList.get(i).getId());
					System.out.printf("\t優先權:%.2f\n", temp);
					processReadyList.get(i).setPriority(temp);
				}
				for (int i = 0; i < processReadyList.size(); i++) {
					if (processReadyList.get(index).getPriority() < processReadyList.get(i).getPriority())
						index = i;
					else if(processReadyList.get(index).getPriority() == processReadyList.get(i).getPriority()&&processReadyList.get(index).getProcessServiceTime()<processReadyList.get(i).getProcessServiceTime()){
						index=i;
					}
				}
			}
		}
		show();// 顯示HRRN演算法的最終結果
	}

時間片輪轉:首先初始化變數,然後按照到達時間順序執行,當程序用完時間片或者程序執行完了,則程序插入就緒佇列尾部或者將程序移除,然後重複上述操作,直到後備佇列和就緒佇列都為空為止。這裡我們需要處理幾個特殊情況:
一:同時到達的多個程序。按預設排列順序執行。
二:當就緒佇列無程序執行,這時後備佇列還有程序

public void RR(ArrayList<PCB> p) {
		int slie=1;
		if (!init(p))
			return;
		while (!(processPoolList.isEmpty() && processReadyList.isEmpty())) { // 程序的執行過程
			PCB process = processReadyList.get(0);
			process.setState("Running");
			informationProcess(process);// 當前程序資訊

			process.setAllTime(process.getAllTime() - slie);// 程序執行階段
			process.setCupTime(process.getCupTime() + slie);

			t+=slie;
			if (!processPoolList.isEmpty()) {// 找該時刻到達的程序
				insertProcess();
			}

			if (process.getAllTime() == 0) {
				result(process);
				process.setState("End");

			} else {
				processReadyList.add(process);

			}
			System.out.println(t + "\t\t" + process.getId() + "\t\t" + process.getAllTime() + "\t\t"
					+ process.getCupTime() + "\t\t" + process.getState());
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			sequence[flag++]=processReadyList.get(0).getId();
			processReadyList.remove(0); // 移除已經執行完的程序
			if (processReadyList.isEmpty() && !processPoolList.isEmpty()) {// 如果就緒“佇列”為空,這找到下一個
				t = processPoolList.get(0).getProcessArrivalTime();
				insertProcess();
			}
		}
		show();// 顯示RR演算法的最終結果
	}

最後介紹一下程序控制塊的內容PCB:

package xin03;

public class PCB {
	private String id; // 程序標識數
	private double priority = 50; // 程序優先數,並規定優先數越大的程序,其優先權
	private int cupTime; // 程序已佔CPU時間
	private int allTime; // 程序還需要佔用CPU時間。當程序執行完畢時,allTime變為0
	private String state; // 程序狀態
	private int processArrivalTime;// 程序到達時間
	private int processServiceTime;// 程序服務時間
	
	private int finished;//程序的完成時間
	private double processWeightedTurnoverTime;//程序的帶權週轉時間
	private int processTurnoverTime;//程序的週轉時間
	
	public PCB() {
	}

	public PCB(String id, int processArrivalTime, int processServiceTime, String state) {
		super();
		this.id = id;
		this.processServiceTime = processServiceTime;
		this.processArrivalTime = processArrivalTime;
		this.state = state;
		this.allTime=processServiceTime;
	}

	public int getFinished() {
		return finished;
	}

	public void setFinished(int finished) {
		this.finished = finished;
	}

	public double getProcessWeightedTurnoverTime() {
		return processWeightedTurnoverTime;
	}

	public void setProcessWeightedTurnoverTime(double processWeightedTurnoverTime) {
		this.processWeightedTurnoverTime = processWeightedTurnoverTime;
	}

	public int getProcessTurnoverTime() {
		return processTurnoverTime;
	}

	public void setProcessTurnoverTime(int processTurnoverTime) {
		this.processTurnoverTime = processTurnoverTime;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public double getPriority() {
		return priority;
	}

	public void setPriority(double priority) {
		this.priority = priority;
	}

	public int getCupTime() {
		return cupTime;
	}

	public void setCupTime(int cupTime) {
		this.cupTime = cupTime;
	}

	public int getAllTime() {
		return allTime;
	}

	public void setAllTime(int allTime) {
		this.allTime = allTime;
	}

	public String getState() {
		return state;
	}

	public void setState(String state) {
		this.state = state;
	}

	public int getProcessArrivalTime() {
		return processArrivalTime;
	}

	public void setProcessArrivalTime(int processArrivalTime) {
		this.processArrivalTime = processArrivalTime;
	}

	public int getProcessServiceTime() {
		return processServiceTime;
	}

	public void setProcessServiceTime(int processServiceTime) {
		this.processServiceTime = processServiceTime;
	}
}

這是測試程式:

package xin03;

import java.util.ArrayList;
import java.util.Scanner;

public class Text {
	public static void main(String[] args) throws Exception {
		showTable();
	}

	public static void showTable() {
		Scanner sr1 = new Scanner(System.in);
		Process process = new Process();
		show();
		int s = 0;
		while (true) {
			try {
				s = sr1.nextInt();
			} catch (Exception e) {
				sr1.nextLine();
				continue;
			}
			switch (s) {
			case 1:
				process.FCFS(input());
				break;
			case 2:
				process.SJF(input());
				break;
			case 3:
				process.HRRN(input());
				break;
			case 4:
				process.RR(input());
				break;
			case 5:
				show();
				break;
			case 6:
				sr1.close();
				System.exit(0);
			default:
				System.out.println("");
			}
		}
	}

	public static void show() {
		System.out.println("**********************************************");
		System.out.println("                   1.FSFC演算法                               ");
		System.out.println("                   2.JSF演算法                                 ");
		System.out.println("                   3.HRRH演算法                               ");
		System.out.println("                   4.RR演算法                                   ");
		System.out.println("                   5.顯示選單                                ");
		System.out.println("                   6.退出                                       ");
		System.out.println("**********************************************");
		System.out.print("請輸入選項:");
	}

	public static ArrayList<PCB> input() {
		Scanner sr = new Scanner(System.in);
		ArrayList<PCB> processList = new ArrayList<PCB>();
		System.out.println("請輸入程序資訊(程序id 程序到達時間  程序服務時間)以end結束:");
		while (true) {
			try {
				String a = sr.next();
				if ("end".equalsIgnoreCase(a))
					break;
				processList.add(new PCB(a, sr.nextInt(), sr.nextInt(), "Ready"));

			} catch (Exception e) {
				sr.nextLine();
				System.out.println("輸入有誤!請重新輸入");

			}
		}
		if (!processList.isEmpty()) {// 判空操作
			for (int i = 0; i < processList.size() - 1; i++) {// 選擇排序對連結串列中元素按到達時間排序
				for (int j = i + 1; j < processList.size(); j++) {
					if (processList.get(i).getProcessArrivalTime() > processList.get(j).getProcessArrivalTime()) {
						PCB process = processList.get(j);
						processList.set(j, processList.get(i));
						processList.set(i, process);
					}
				}
			}
		}
		return processList;
	}
}

ps:如果各位大佬發現有什麼不足的地方或者有需要程式碼的同學,請留言喲!!!!