處理機排程-輪轉排程演算法(RR)
阿新 • • 發佈:2018-12-12
在分時系統中,最簡單也是較常用的是基於時間片的輪轉排程演算法,該演算法採取了非常公平的處理機分配方式,即讓就緒佇列上的每個程序每次僅執行一個時間片。如果就緒佇列有n個程序,則每個程序每次大約都可獲得1/n的處理機時間。
演算法思想:讓就緒佇列的每個程序每次僅執行一個時間片。每隔一段時間產生一次中斷,啟用系統中的程序排程程式,將cpu分配給隊首程序,當時間片耗盡或執行完畢時,再將cpu分配給新的隊首程序。可保證就緒佇列中的所有程序在一個確定的時間內,都能後的一次時間片執行。
所需資料結構:
//程序 struct Process { int id; //程序標記 int start_time; //進入時間 int surves_time; //服務時間 int turnover_time; //週轉時間 int end_time; //結束時間 double priority; //權值 };
輔助函式:
//按照進入時間進行比較
bool cmp1(const Process &p1,const Process &p2)
{
return p1.start_time < p2.start_time;
}
實現過程:
這次我們用一個連結串列作為就緒佇列來儲存程序,方便我們的刪除。
time 為時間片大小。
void RR(queue<int> &q, Process *p, int n, int time) { int i, j, finish; list<Process> L; //就緒佇列 list<Process>::iterator it; //執行指標 vector<Process> result; //儲存結果 sort(p, p+n, cmp1); finish = 0; j = 0; while(!L.empty() || j < n) //當就緒佇列不空或者還有程序沒有執行 { if(L.empty()) //如果就緒對列為空 { //從程序佇列中選擇隊首元素加入就緒佇列 finish = p[j].start_time; //修改當前時間為程序的進入時間 L.push_back(p[j++]); it = L.begin(); //修改執行指標 } if(it == L.end()) //執行指標到了隊尾,從隊首開始 it = L.begin(); q.push(it->id); if(it->surves_time <= time) //程序執行完成 { finish += it->surves_time; //修改當前時間 while(j<n && p[j].start_time<=finish) //立刻檢查是否有程序到來,若有加入就緒佇列的末尾 L.push_back(p[j++]); it->end_time = finish; it->turnover_time = it->end_time - it->start_time; result.push_back(*it); //儲存結果 it = L.erase(it); //刪除當前程序,L.erase() 返回迭代器的下一位 } else { finish += time; while(j<n && p[j].start_time<=finish) L.push_back(p[j++]); it->surves_time -= time; it++; //執行指標執行下一個程序 } } for(i = 0; i < n; i++) //將結果儲存,用於輸出 p[i] = result[i]; }