【操作系统】代码实践:先来先服务调度算法(FCFS),短进程优先调度算法(SJF),高响应比优先调度算法(HRRN)
文章目錄
- 一、實驗需求
- 二、需求分析
- 三、效果展示
- (1)FCFS 調度算法
- (2)SJF 調度算法
- (3)HRRN 調度算法
- (4)綜合對比
- 四、具體代碼
一、實驗需求
設計一個有N個進程的進程調度程序,實現先來先服務調度算法,
,短進程優先調度算法,動態最高優先數優先調度算法。
二、需求分析
進程對象的信息抽象成此PCB類
為PCB類編寫常用Getter/Setter,構造方法(利用random隨機數實現進程實際情況中的隨機性),并模擬實現進程運行及阻塞時對應時間屬性值的動態變化(自減1)等等。
1、FCFS算法最容易實現,因此只需判斷當前時間time的值,是否等于進程序列中的第一個進程的到達時間即可,并不斷輸出當前時間和進程執行情況,例如其執行時間和剩余時間,最后再提示進程執行完畢,并輸出周轉時間,在序列中刪除此進程結點等等。
2、其次是SJF算法,此算法需額外設置一個就緒進程序列,根據當前time值,將已經達到執行開始時間的進程放入進程的就緒隊列,并刪除在原進程序列中的此進程結點,模擬進程的狀態變化與多隊列機制,當就緒隊列中有進程且數量不為一個時,則對此就緒隊列的進程按照進程執行時間從小到大排序,并記錄此次最優先進程(即最短進程的pid),則在下輪進行就緒進程隊列的排序時,便可根據第一個隊列中進程結點的pid是否為之前記錄的pid得知進程是否被搶占,從而輸出提示信息,進而輸出其他信息。
3、最后,相對較麻煩的是HRRN算法,此算法,與SJF算法的實現類似,主要區別是,將SJF算法中就緒進程隊列的排序依據,從進程執行時間最短,轉為進程優先級最高,并額外再增加一個進程阻塞隊列(根據實驗要求),而阻塞隊列也是根據阻塞的開始時間,與阻塞的過程時間來與當前time時間值進行判斷的,因此,在SJF算法的基礎上,HRRN算法的實現也就變的不再相對復雜,因此一開始聲明的HRRN的復雜是相對于從0開始編寫的復雜性。
三、效果展示
具體執行結果如下:
(1)FCFS 調度算法
(2)SJF 調度算法
(3)HRRN 調度算法
(還為實現完整,這只是簡單的優先級調度算法,優先數不具有動態變化性)
(內容較多,只截取部分)
(4)綜合對比
(情況隨機,只截取一張圖。其實此處只有HRRN算法中考慮了阻塞時間,而前兩種算法并未考慮,因此,由于此變量不唯一,因此此情況下的比較也無意義,但可以直觀地顯示結果,也可以改進此程序代碼,賦予其真正的意義)
四、具體代碼
class PCB {private int pid; // 進程idprivate int priority; // 進程優先級private int arrTime; // 到達時間private int allTime; // 還需運行時間private int cpuTime; // 已運行時間private int startBlockTime; // 開始阻塞時間private int blockTime; // 阻塞時間private String state; // 狀態public PCB(int pid, int priority, int arrTime, int allTime, int cpuTime, int startBlockTime, int blockTime, String state) {this.pid = pid;this.priority = priority;this.arrTime = arrTime;this.allTime = allTime;this.cpuTime = cpuTime;this.startBlockTime = startBlockTime;this.blockTime = blockTime;this.state = state;}public int getPid() {return pid;}public void setPid(int pid) {this.pid = pid;}public int getPriority() {return priority;}public void setPriority(int priority) {this.priority = priority;}public int getArrTime() {return arrTime;}public void setArrTime(int arrTime) {this.arrTime = arrTime;}public int getAllTime() {return allTime;}public void setAllTime(int allTime) {this.allTime = allTime;}public int getCpuTime() {return cpuTime;}public void setCpuTime(int cpuTime) {this.cpuTime = cpuTime;}public int getStartBlockTime() {return startBlockTime;}public void setStartBlockTime(int startBlockTime) {this.startBlockTime = startBlockTime;}public int getBlockTime() {return blockTime;}public void setBlockTime(int blockTime) {this.blockTime = blockTime;}public String getState() {return state;}public void setState(String state) {this.state = state;}/*** HRRN 執行情況模擬*/public void show_HRRN() {System.out.println("進程:" + pid +" 優先級:" + priority +" 到達時間:" + arrTime +" 還需運行時間:" + allTime +" 已運行時間:" + cpuTime +" 開始阻塞時間:" + startBlockTime +" 阻塞時間:" + blockTime +" 狀態:" + state);}/*** SJF FCFS 執行情況模擬*/public void show_SJF_FCFS() {System.out.println("進程:" + pid +"正在執行,到達時間:" + arrTime +" 還需運行時間:" + allTime +" 已運行時間:" + cpuTime);}public void toBlock() {state = "Block";}public void toRun() {state = "Run";}public void toFinish() {state = "Finish";}public void toReady() {state = "Ready";}public void running() { // 進程運行時的狀態變化allTime -= 1;cpuTime += 1;}public void toStartBlock() { // 進程將要開始阻塞時的狀態變化if (startBlockTime > 0) {startBlockTime -= 1;}}public void blocking() { // 進程阻塞時的狀態變化if (blockTime > 0) {blockTime -= 1;}priority += 1;} }public class Main {/*** 初始化進程,生成四個進程并按到達時間講它們放入列表 list* @param num*/public static List<PCB> init(int num) {List<PCB> list = new ArrayList<PCB>();for (int i = 0; i < num; i++) {// 構造參數:進程id,優先級,到達時間,還需運行時間,// 已運行時間,開始阻塞時間,阻塞時間,狀態list.add(new PCB(i, random(1, 10), random(1, 15), random(1, 10),0, random(5, 10), random(1, 10), "Ready"));}// 將各進程按 到達時間 從小到大排列for (int i = 0; i < list.size() - 1; i++) {for (int j = i + 1; j < list.size(); j++) {if (list.get(i).getArrTime() > list.get(j).getArrTime()) {PCB temp = list.get(i);list.set(i, list.get(j));list.set(j, temp);}}}return list;}public static int random(int m, int n) {Random random = new Random();return (int) Math.round(random.nextDouble() * n) + m;}/*** 先來先服務算法* @param list*/public static int FCFS(List<PCB> list) {int time = 0;while (true) {System.out.println("time: " + time);PCB pcb = list.get(0);if (time >= pcb.getArrTime()) {pcb.running();pcb.show_SJF_FCFS();if (pcb.getAllTime() == 0) {System.out.println("進程" + pcb.getPid() + "執行完畢,周轉時間:" +(time - pcb.getArrTime()) + "\n");list.remove(list.get(0));}}time += 1;if (list.size() == 0) {return --time;}}}/*** 搶占式短作業優先* @param list*/public static int SJF(List<PCB> list) {List<PCB> readyList = new ArrayList<PCB>(); // 就緒隊列int time = 0;int pid = 0;while (true) {int readyListLength = readyList.size();System.out.println("time: " + time);if (list.size() > 0) {int i = 0;while (true) { // 將進程放入就緒隊列,就緒隊列的第一個是正在執行的進程if (time == list.get(i).getArrTime()) {readyList.add(list.get(i));list.remove(list.get(i));pid = readyList.get(0).getPid(); // 獲取就緒隊列第一個進程的IDi -= 1;}i += 1;if (i >= list.size()) {break;}}}if (readyList.size() >= 2 && readyList.size() != readyListLength) { // 判斷就緒隊列中最短的作業readyListLength = readyList.size();for (int i = 0; i < readyList.size() - 1; i++) {for (int j = i + 1; j < readyList.size(); j++) {if (readyList.get(i).getAllTime() > readyList.get(j).getAllTime()) {PCB temp = readyList.get(i);readyList.set(i, readyList.get(j));readyList.set(j, temp);}}}}if (readyList.size() > 0) { // 執行進程if (pid != readyList.get(0).getPid()) { // 如果正在執行的進程改變,則發送搶占System.out.println("發生搶占,進程" + readyList.get(0).getPid() + "開始執行");pid = readyList.get(0).getPid();}readyList.get(0).running();readyList.get(0).show_SJF_FCFS();if (readyList.get(0).getAllTime() == 0) {System.out.println("進程" + readyList.get(0).getPid() + "執行完畢,周轉時間:" + (time - readyList.get(0).getArrTime() + 1));readyList.remove(readyList.get(0));if (readyList.size() > 0) {pid = readyList.get(0).getPid();}}}time += 1;if (readyList.size() == 0 && list.size() == 0) {break;}}return --time;}public static int HRRN(List<PCB> list) { // 動態最高優先數優先List<PCB> readyList = new ArrayList<PCB>(); // 就緒隊列List<PCB> blockList = new ArrayList<PCB>(); // 阻塞隊列int time = 0;int pid = 0;while (true) {System.out.println("time: " + time);if (list.size() > 0) {int i = 0;while (true) { // 將進程放入就緒隊列if (time == list.get(i).getArrTime()) {readyList.add(list.get(i));list.remove(list.get(i));pid = readyList.get(0).getPid();i -= 1;}i += 1;if (i >= list.size()) {break;}}}for (int i = 0; i < readyList.size() - 1; i++) { // 將就緒隊列的進程按優先級大小排列for (int j = i + 1; j < readyList.size(); j++) {if (readyList.get(i).getPriority() < readyList.get(j).getPriority()) {readyList.get(i).toReady();PCB temp = readyList.get(i);readyList.set(i, readyList.get(j));readyList.set(j, temp);}}}if (readyList.size() > 0) { // 執行過程if (pid != readyList.get(0).getPid()) {System.out.println("發生搶占,進程" + readyList.get(0).getPid() + "開始執行");pid = readyList.get(0).getPid();}if (readyList.get(0).getStartBlockTime() > 0 || readyList.get(0).getBlockTime() <= 0) {readyList.get(0).toRun();readyList.get(0).running();readyList.get(0).toStartBlock();}for (int i = 1; i < readyList.size(); i++) {readyList.get(i).setPriority(readyList.get(i).getPriority() + 1);readyList.get(i).toStartBlock();}}if (blockList.size() > 0) { // 阻塞隊列blockList.forEach(pcb -> {pcb.blocking();});}readyList.forEach(pcb -> {pcb.show_HRRN();});blockList.forEach(pcb -> {pcb.show_HRRN();});if (readyList.size() > 0) { // 當進程開始阻塞事件為0,將進程放入阻塞隊列int i = 0;while (true) {if (readyList.size() > 0) {if (readyList.get(i).getStartBlockTime() == 0 && readyList.get(i).getBlockTime() != 0) {System.out.println("進程" + readyList.get(i).getPid() + "開始阻塞,進入阻塞隊列");readyList.get(i).toBlock();blockList.add(readyList.get(i));readyList.remove(readyList.get(i));i -= 1;}}i += 1;if (i >= readyList.size()) {break;}}}if (blockList.size() > 0) {int i = 0;while (true) {if (blockList.get(i).getBlockTime() == 0) {System.out.println("進程" + blockList.get(i).getPid() + "阻塞結束,進入就緒隊列");blockList.get(i).toReady();readyList.add(blockList.get(i));blockList.remove(blockList.get(i));pid = readyList.get(0).getPid();i -= 1;}i += 1;if (i >= blockList.size()) {break;}}}if (readyList.size() > 0) { // 進程執行完畢則移出就緒隊列if (readyList.get(0).getAllTime() <= 0) {readyList.get(0).toFinish();System.out.println("進程" + readyList.get(0).getPid() + "執行完畢,周轉時間: " +(time - readyList.get(0).getArrTime() + 1) + ",狀態:" + readyList.get(0).getState());readyList.remove(readyList.get(0));if (readyList.size() > 0) {pid = readyList.get(0).getPid();}}}time += 1;if (list.size() == 0 && readyList.size() == 0 && blockList.size() == 0) {break;}}return --time;}public static List<PCB> cloneList(List<PCB> list) {List<PCB> listClone = new ArrayList<PCB>();for (int i = 0; i < list.size(); i++) {PCB pcb = list.get(i);PCB pcbClone = new PCB(pcb.getPid(), pcb.getPriority(), pcb.getArrTime(), pcb.getAllTime(),pcb.getCpuTime(), pcb.getStartBlockTime(), pcb.getBlockTime(), pcb.getState());listClone.add(pcbClone);}return listClone;}public static void main(String[] args) {while (true) {System.out.println("請選擇算法:---------------");System.out.println("1、先來先服務");System.out.println("2、搶占式短作業優先");System.out.println("3、動態最高優先數優先");System.out.println("4、比較上述三種算法");System.out.println("------------------------");Scanner reader = new Scanner(System.in);System.out.print("請輸入選項:");int select = reader.nextInt();switch (select) {case 1:List<PCB> list = init(4);list.forEach(pcb -> {pcb.show_SJF_FCFS();});FCFS(list);break;case 2:List<PCB> list2 = init(4);list2.forEach(pcb -> {pcb.show_SJF_FCFS();});SJF(list2);break;case 3:List<PCB> list3 = init(4);list3.forEach(pcb -> {pcb.show_HRRN();});HRRN(list3);break;case 4:int time_FCFS = 0;int time_SJF = 0;int time_HRRN = 0;List<PCB> list4 = init(4);if (list4.size() > 0) {List<PCB> list4_1 = cloneList(list4);List<PCB> list4_2 = cloneList(list4);List<PCB> list4_3 = cloneList(list4);List<PCB> list4_all = cloneList(list4);System.out.println("**************FCFS******************");for (int i = 0; i < list4_1.size(); i++) {list4_1.get(i).show_SJF_FCFS();};time_FCFS = FCFS(list4_1);System.out.println("********************************");System.out.println("****************SJF****************");for (int i = 0; i < list4_2.size(); i++) {list4_2.get(i).show_SJF_FCFS();};time_SJF = SJF(list4_2);System.out.println("********************************");System.out.println("*****************HRRN***************");for (int i = 0; i < list4_3.size(); i++) {list4_3.get(i).show_HRRN();};time_HRRN = HRRN(list4_3);System.out.println("********************************");System.out.println("=================情況綜述======================");System.out.println("=======進程情況========");for (int i = 0; i < list4_all.size(); i++) {list4_all.get(i).show_HRRN(); // 此方法的進程打印信息最全};System.out.println("FCFS 算法執行時間:" + time_FCFS);System.out.println("SJF 算法執行時間:" + time_SJF);System.out.println("HRRN 算法執行時間:" + time_HRRN);System.out.println("=======================================");}break;}}} }總結
以上是生活随笔為你收集整理的【操作系统】代码实践:先来先服务调度算法(FCFS),短进程优先调度算法(SJF),高响应比优先调度算法(HRRN)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: css --- [读书笔记] 浮动(f
- 下一篇: 清华大学-曾鸣-《ARM微控制器与嵌入式