1. 程式人生 > >基於Bootstrap的h5簡單模擬CPU排程演算法

基於Bootstrap的h5簡單模擬CPU排程演算法

一、說明

模擬了下面四種CPU排程演算法

  1. FCFS,先到先服務
  2. SRTF,搶佔式最短剩餘時間優先
  3. RR,輪詢
  4. 搶佔式優先順序

實驗要求

  1. gantt圖
  2. 計算每個程序的等待時間
  3. 計算平均等待時間
  4. 考慮CPU空閒的情況

其他

  1. 前端使用了Bootstrap框架,因為時間緊迫而且確實效果還行。
  2. github地址:https://github.com/cuguniang/CPU_Schedual

二、實現效果

  1. 程序資訊
    在這裡插入圖片描述

  2. FCFS
    在這裡插入圖片描述

  3. SRTF
    在這裡插入圖片描述

  4. RR
    在這裡插入圖片描述

  5. 優先順序
    在這裡插入圖片描述
    在這裡插入圖片描述

  6. CPU空閒的情況
    在這裡插入圖片描述

在這裡插入圖片描述

三、實現時的一些思考

  1. 使用者新增的順序 != CPU排程的順序,需要重新排序,而希望程序列表中顯示的順序仍是使用者輸入的順序,所以在實現排程前,先深拷貝使用者輸入的陣列。
    在這裡插入圖片描述

  2. gantt圖使用彩色塊看起來效果更好,本來想在一個大div裡塞小div,但很醜。決定用bs的進度條元件,這是用bs框架的最重要的原因!但具體實現的時候,其實還是往大div裡塞小div,只不過這裡的div具有bs的class。
    gantt圖效果:
    在這裡插入圖片描述
    對應的html:
    在這裡插入圖片描述

  3. 學會用array的sort和比較函數了,如下

scheual_process.sort(function (a, b) {
	//到達時間一樣,短作業優先
	if(a.arrival_time == b.arrival_time){
		return a.CPU_brust - b.CPU_brust;
	}
	//否則按到達時間排序
	return a.arrival_time - b.arrival_time;
});	
  1. 希望每段程序的CPU區間顏色不同,採用bs提供的progress-bar-xxx類,xxx=primary|warning|error|sucess|info,分別具有不同的顏色,一開始隨機獲取陣列中一個值,作為每段的顏色。但是相鄰的兩段有時候就會顏色相同,於是就按順序迴圈取:希望每段程序的CPU區間顏色不同,採用bs提供的progress-bar-xxx類,xxx=primary|warning|error|sucess|info,分別具有不同的顏色,一開始隨機獲取陣列中一個值,作為每段的顏色。但是相鄰的兩段有時候就會顏色相同,於是就按順序迴圈取:
var COLOR = {	
	color:["primary","warning","success","danger","default","info"],
	index:0
			};
function getColor(){
	return COLOR.color[(COLOR.index++)%COLOR.color.length];
}
  1. 搶佔實在是太難寫了。當前程序結束時,如果沒有別的程序,它就空閒,否則選擇一個剩餘時間最短的程序來執行;如果沒執行完,一個新的程序就來到了,判斷它的剩餘時間和新程序的剩餘時間,新程序更短的話,就搶佔。最外層迴圈條件是:
while(scheual_process.length>0 || ready_queue.length>0){
	...
	//多種情況
	1. CPU空閒
	2. now_p結束時next_p還未到達 => ready_queue中還有沒有程序?
	3. 剛好在結束時到達 => 加入ready_queue一起排序
	4. 未結束時到達,可能搶佔 => 比較剩餘時間
}
  1. 寫了兩個類,Process用來排程,Bar用來繪製gantt圖
function Process(process_name,arrival_time,CPU_brust,priority) {
	this.process_name = process_name;
	this.arrival_time = arrival_time;
	this.CPU_brust = CPU_brust;
	this.priority = priority;
	this.remaining_time = CPU_brust;
	this.waiting_time = 0;
	this.start_time = 0;
	this.end_time = 0;
	return this;
}

function Bar(name,start,end,color){//for gantt
	this.name = name;
	this.start = start;
	this.end = end;
	this.color = color;

	return this;
}

附:利用Bar的物件陣列bars來繪製gantt,包括下面的數字

function process_painter(bars,total_brust){
	for(var i = 0;i < bars.length;i++){
		var num = $("<span></span>");
		var bar = $("<div></div>").addClass("progress-bar");

		bar.addClass("progress-bar-"+bars[i].color);//程序顏色
		bar.text(bars[i].name);//程序名字
		bar.css('width',((bars[i].end-bars[i].start)/total_brust*100)+"%");//程序比例
		$("#gantt").append(bar);

		num.text(bars[i].end);
		num.css('width',(bars[i].end-bars[i].start)/total_brust*100-0.5+"%");
		$("#gantt_num").append(num);		
	}
}

在每個排程演算法中往bars裡新增元素,如

bars.push(new Bar(p.process_name,now_time,now_time+time_q,getColor()));

最後呼叫process_painter()方法即可

process_painter(bars,now_time);

  1. 如果一個程序分開執行了多次,每次等待時間就不能用now_time-減去arrival_time。要考慮是不是第一次執行到它,而且每次排程時,要更新它的start_time和end_time。(SRTF中程式碼如下)
if(now_p.CPU_brust == now_p.remaining_time){//第一次執行到它
	now_p.start_time = now_time;
	now_p.waiting_time += now_p.start_time - now_p.arrival_time;
}
else{
	now_p.waiting_time = now_time - (now_p.end_time-now_p.start_time);
	now_p.start_time = now_time;
}			
  1. 被array的splice方法坑死(最開始還拼錯了),第一個引數是index,最終改成這樣才能把這個執行完的now_p給移除。
ready_queue.splice(ready_queue.indexOf(now_p),1);
  1. 優先順序就是把SRTF的實現複製過來,改了搶佔的條件和一點點細節(比如對remaining_time的處理)。實際上搶佔式的優先順序就是一般化的SRTF,SRTF的原則是剩餘時間短 = 優先順序高,而優先順序是直接給了個數值代表優先順序。注意small int ≡ high priority

四、反思

  1. Process類的定義應該從PCB的結構出發來考慮。
  2. 切換程序時,應該寫一個類似切換上下文的函式。把對各種時間的設定寫進函式裡。