1. 程式人生 > >處理機排程-輪轉排程演算法(RR)

處理機排程-輪轉排程演算法(RR)

在分時系統中,最簡單也是較常用的是基於時間片的輪轉排程演算法,該演算法採取了非常公平的處理機分配方式,即讓就緒佇列上的每個程序每次僅執行一個時間片。如果就緒佇列有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];
}