基於Bootstrap的h5簡單模擬CPU排程演算法
阿新 • • 發佈:2018-12-31
一、說明
模擬了下面四種CPU排程演算法
- FCFS,先到先服務
- SRTF,搶佔式最短剩餘時間優先
- RR,輪詢
- 搶佔式優先順序
實驗要求
- gantt圖
- 計算每個程序的等待時間
- 計算平均等待時間
- 考慮CPU空閒的情況
其他
- 前端使用了Bootstrap框架,因為時間緊迫而且確實效果還行。
- github地址:https://github.com/cuguniang/CPU_Schedual
二、實現效果
-
程序資訊
-
FCFS
-
SRTF
-
RR
-
優先順序
-
CPU空閒的情況
三、實現時的一些思考
-
使用者新增的順序 != CPU排程的順序,需要重新排序,而希望程序列表中顯示的順序仍是使用者輸入的順序,所以在實現排程前,先深拷貝使用者輸入的陣列。
-
gantt圖使用彩色塊看起來效果更好,本來想在一個大div裡塞小div,但很醜。決定用bs的進度條元件,這是用bs框架的最重要的原因!但具體實現的時候,其實還是往大div裡塞小div,只不過這裡的div具有bs的class。
gantt圖效果:
對應的html:
-
學會用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;
});
- 希望每段程序的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];
}
- 搶佔實在是太難寫了。當前程序結束時,如果沒有別的程序,它就空閒,否則選擇一個剩餘時間最短的程序來執行;如果沒執行完,一個新的程序就來到了,判斷它的剩餘時間和新程序的剩餘時間,新程序更短的話,就搶佔。最外層迴圈條件是:
while(scheual_process.length>0 || ready_queue.length>0){
...
//多種情況
1. CPU空閒
2. now_p結束時next_p還未到達 => ready_queue中還有沒有程序?
3. 剛好在結束時到達 => 加入ready_queue一起排序
4. 未結束時到達,可能搶佔 => 比較剩餘時間
}
- 寫了兩個類,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);
- 如果一個程序分開執行了多次,每次等待時間就不能用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;
}
- 被array的splice方法坑死(最開始還拼錯了),第一個引數是index,最終改成這樣才能把這個執行完的now_p給移除。
ready_queue.splice(ready_queue.indexOf(now_p),1);
- 優先順序就是把SRTF的實現複製過來,改了搶佔的條件和一點點細節(比如對remaining_time的處理)。實際上搶佔式的優先順序就是一般化的SRTF,SRTF的原則是剩餘時間短 = 優先順序高,而優先順序是直接給了個數值代表優先順序。注意small int ≡ high priority
四、反思
- Process類的定義應該從PCB的結構出發來考慮。
- 切換程序時,應該寫一個類似切換上下文的函式。把對各種時間的設定寫進函式裡。