1. 程式人生 > >多級反饋佇列排程(模擬實現)

多級反饋佇列排程(模擬實現)

演算法描述(來自百度): 1、程序在進入待排程的佇列等待時,首先進入 優先順序最高的Q1等待。 2、首先排程優先順序高的佇列中的程序。若高優先順序中佇列中已沒有排程的程序,則排程次 優先順序佇列中的程序。例如:Q1,Q2,Q3三個佇列,當且僅當在Q1中沒有程序等待時才去排程Q2,同理,只有Q1,Q2都為空時才會去排程Q3。 3、對於同一個佇列中的各個程序,按照FCFS分配時間片排程。比如Q1佇列的 時間片為N,那麼Q1中的作業在經歷了N個時間片後若還沒有完成,則進入Q2佇列等待,若Q2的時間片用完後作業還不能完成,一直進入下一級佇列,直至完成。 4、在最後一個佇列QN中的各個程序,按照時間片輪轉分配時間片排程。 5、
在低 優先順序的佇列中的程序在執行時,又有新到達的作業,此時須立即把正在執行的程序放回當前佇列的隊尾,然後把處理機分給高優先順序程序。換而言之,任何時刻,只有當第1~i-1佇列全部為空時,才會去執行第i佇列的程序( 搶佔式)。特別說明,當再度執行到當前佇列的該程序時, 僅分配上次還未完成的時間片,不再分配該佇列對應的完整時間片。   雖然演算法描述已經十分詳細了,但是有些資料上的描述不是很詳細,這裡再從申下重點: 1、該演算法為搶佔式演算法 演算法描述已經表達的很清楚了,只有高優先順序佇列為空時低優先順序佇列上的程序才可能得到執行,言下之意,若當前時刻cpu分配給了低優先順序對列的程序,那麼就意味者所有優先順序高於當前佇列的就緒佇列均無程序,而此時若有新的程序進入高優先順序的對列,那麼當前程序立即停止執行,然後執行高優先順序對列上的程序(有些人可能會認為會等該程序的時間片執行完了,才會再次排程,這和以上的演算法描述顯然不符,而我接觸的一些關於該演算法的演算法描述都是前面的演算法的描述,如果我所參考演算法描述有誤,請不吝指出,謝謝。) 2、當基於 1 中低優先順序佇列的正在執行的程序被cpu被搶佔後重新進入當前佇列的隊尾後,時間片的分配在演算法描述裡也寫的很清楚, 僅分配上次還未完成的時間片,不再分配該佇列對應的完整時間片。

注意到以上兩點應該沒有什麼大問題了。   模擬思路: 分析: 該演算法的難點應該時對於不同型別的優先佇列上程序執行時的處理; 主要時搶佔時的對於個佇列的處理,和當前程序的保護現場; 這裡建議先分析佇列的型別和程序的型別,然後考慮對應的操作 佇列型別:Q1,Q2,Q3 Q1:最高優先順序的佇列 Q2:除最高優先順序佇列和最低優先順序佇列 Q3:最低優先順序的佇列 Q4:為了模擬程序邊執行邊進入佇列的過程而設立的佇列,在排程前將所有程序和相關資訊存入,然後再排程過程中模擬進入系統   程序型別:P1,P2,P3,P4 P1:原本位於Q1的佇列,被排程後得到CPU P2:原本位於Q2的佇列,被排程後得到CPU P3:原本位於Q3的佇列,被排程後得到CPU P4:原本位於Q4的佇列,噹噹前時間等於程序到達時間,將其從Q4中取出,並置入Q1佇列的隊尾 P5:位於Q1,Q2,Q3佇列上的,為得到排程的程序,本演算法不對其進行操作   思路: 可以對於每個時刻對所有程序佇列和當前執行的狀態進行監控,然後對不同的狀態進行不同的響應; 那麼顯然對於P1,沒有被搶佔的可能,那麼在其執行時,只需對與每個時刻考慮是否有新的程序進入Q1, 這裡可以直接令其的已得到cpu時間直接加上其佇列對應的時間片長度,然後用一個迴圈遍歷該程序進入的時刻T_p_1到該程序執行完所得時間片t_s_1的時刻T_p_1+t_s_1,詢問佇列Q4是否有新的程序到達,若有,將其加入Q1。如果時間片用完仍未完成,令其進入下一佇列的隊尾,否則,將程序狀態改為FINISHED,結束執行,讓出cpu。   對於P2,存在被搶佔的可能,那麼在其執行時,用一個迴圈來遍歷其得到cpu的時刻T_p_2到該程序執行完所得到的時間片的長度T_p_2+t_s_2,若無新程序到達,那麼令其所得到cpu的時間加1個單位,若有,則將該佇列加入其排程前所在佇列的隊尾。然後結束執行並讓出 cpu。如果時間片用完仍未完成,令其進入下一佇列的隊尾,否則,將程序狀態改為FINISHED,結束執行,讓出cpu。(注意Q2,P2代表的對於操作相似的一類程序和佇列,而不是特指某一和佇列上的被排程程序和某一佇列)   對於P3,存在被搶佔的可能,那麼在其執行時,用一個迴圈來遍歷其得到cpu的時刻T_p_3到該程序執行完所得到的時間片的長度T_p_3+t_s_3,若無新程序到達,那麼令其所得到cpu的時間加1個單位,若有,則將該佇列加入其排程前所在佇列的隊尾。然後結束執行並讓出 cpu。如果時間片用完仍未完成,令其進入當前佇列的隊尾,並置使用時間片為0,否則,將程序狀態改為FINISHED,結束執行,讓出cpu。   說了這麼多,貼程式碼了:   #include<bits/stdc++.h>
using namespace std; int  TIME_SLICE=1;
int  HIGHER_TIME_SLICE=1;
int MIDDLE_TIME_SLICE=1;
int LOWER_TIME_SLICE=1;
const string IN_HIGHER="in higher";
const string IN_MIDDLE="in middle";
const string IN_LOWER="in lower";
const string FREE="FREE";
const string HIGH="HIGH";
const string MIDDLE="MIDDLE";
const string LOWER="LOWER"; const string FINISH="FINISH";
const string READY="READY";
const string RUNNING="RUNNING"; class process
{
private:
    string process_name;
    string status;
    int arrive_time;
    int service_time;
    int ran_time;
    int time_slice=0;
    int now_time;
public:
    process(string process_name,int arrive_time,int service_time,int ran_time,string status);     string get_process_name();
    void printf_infomation();
    int run(int now_time);
    bool is_arrive(int now_time);
    int get_arrive_time();
    process copyself(); };
list<process> higher_list;
list<process> middle_list;
list<process> lower_list;
list<process> process_list;
list<process>::iterator iter;
process process::copyself()
{
    string process_name=this->process_name;
    string status=this->status;
    int arrive_time=this->arrive_time;
    int service_time=this->service_time;
    int ran_time=this->ran_time;
    int time_slice=this->time_slice;
    int now_time=this->now_time;
    return process(process_name,arrive_time,service_time,ran_time,status);
}
process::process(string process_name,int arrive_time,int service_time,int ran_time,string status)
{
    this->process_name=process_name;
    this->arrive_time=arrive_time;
    this->service_time=service_time;
    this->ran_time=ran_time;
    this->status=status;
}
string process::get_process_name()
{
    return this->process_name;
} void process::printf_infomation()
{
    cout<<"程序名 : "<<this->process_name<<endl;
    cout<<"到達時間 : "<<this->arrive_time<<endl;
    cout<<"需要執行的時間 : "<<this->service_time<<endl;
    cout<<"已使用cpu的時間  : "<<this->ran_time<<endl;
    cout<<"程序當前狀態 : "<<this->status<<endl;
};
int  process::run(int now_time)
{
    this->now_time=now_time;
    this->status=RUNNING;
    cout<<"現在是 "<<this->now_time<<"時刻 。"<<endl;
    cout<<" 第一佇列的程序如下:";
    for(iter=higher_list.begin(); iter!=higher_list.end(); iter++)
        cout<<iter->get_process_name()<<' ';
    cout<<endl;
    cout<<"第二佇列的程序如下:";
    for(iter=middle_list.begin(); iter!=middle_list.end(); iter++)
        cout<<iter->get_process_name()<<' ';
    cout<<endl;
    cout<<"第三佇列的程序如下:";
    for(iter=lower_list.begin(); iter!=lower_list.end(); iter++)
        cout<<iter->get_process_name()<<' ';
    cout<<endl<<endl;
    cout<<"正在執行的程序資訊如下:"<<endl;
    this->printf_infomation();
    if(this->ran_time==0)
        {
        this->time_slice=min(this->service_time,HIGHER_TIME_SLICE);
            cout<<this->process_name<<"正在使用第一佇列時間片!"<<endl<<endl;
        for(int i=1; i<=this->time_slice; i++)
            {
            this->now_time++;
            while(true)
                {
                if(!process_list.empty()&&process_list.front().is_arrive(this->now_time))
                    {
                    process first=process_list.front();
                    process_list.pop_front();
                    higher_list.push_back(first);
                    }
                else
                    {
                    break;
                    }
                }
            }
        this->ran_time+=this->time_slice;
        if(this->service_time==this->ran_time)
            {
            cout<<"現在是 "<<this->now_time<<"時刻,程序"<<this->process_name<<"已完成"<<"1"<<endl<<endl;
            }
        else
            {
            this->status=READY;
            process temp=this->copyself();
            middle_list.push_back(temp);
            }
        return this->now_time;
        }
    else if(this->ran_time<HIGHER_TIME_SLICE+MIDDLE_TIME_SLICE)
        {         this->time_slice=MIDDLE_TIME_SLICE;
        cout<<this->process_name<<"正在使用第二佇列時間片!"<<endl<<endl;
        for(int i=this->ran_time+1; i<=this->time_slice+HIGHER_TIME_SLICE&&i<=this->service_time; i++)
            {
            bool flag=false;
            this->now_time++;
            this->ran_time++;
            while(true)
                {
                if(!process_list.empty()&&process_list.front().is_arrive(this->now_time))
                    {
                    flag=true;
                    process first=process_list.front();
                    process_list.pop_front();
                    higher_list.push_back(first);
                    }
                else
                    {
                    break;
                    }
                }
            if(flag)
                {
                this->status=READY;
                 process temp=this->copyself();
                middle_list.push_back(temp);
                return this->now_time;
                }
            }         if(this->ran_time==this->service_time)
            {
            cout<<"現在是 "<<this->now_time<<"時刻,程序"<<this->process_name<<"已完成"<<endl;
            }
        else
            {
            this->status=READY;
            process temp=this->copyself();
            lower_list.push_back(temp);
            }
        return this->now_time;
        }
    else
        {
        this->time_slice=LOWER_TIME_SLICE-((this->ran_time-HIGHER_TIME_SLICE-MIDDLE_TIME_SLICE)%LOWER_TIME_SLICE);
        cout<<this->process_name<<"正在使用第三佇列時間片!"<<endl<<endl;
        bool flag=false;
        for(int i=1; i<=this->time_slice&&this->ran_time<this->service_time; i++)
            {
            this->now_time++;
            this->ran_time++;
            while(true)
                {
                if(!process_list.empty()&&process_list.front().is_arrive(this->now_time))
                    {
                    flag=true;
                    process first=process_list.front();
                    process_list.pop_front();
                    higher_list.push_back(first);
                    }
                else
                    {
                    break;
                    }
                }
            if(flag)
                {
                     process temp=this->copyself();
                lower_list.push_back(temp);
                return this->now_time;
                break;
                }
            }
        if(this->ran_time<this->service_time)
            {
            this->status=READY;
             process temp=this->copyself();
            lower_list.push_back(temp);
            return this->now_time;
            }
        else
            {
            this->status=FINISH;
            cout<<"現在是 "<<this->now_time<<"時刻,程序"<<this->process_name<<"已完成"<<"2"<<endl;
            return this->now_time;
            }
        }
}
bool  process::is_arrive(int now_time)
{
    if(this->arrive_time<=now_time)
        return true;
    else return false;
}
int  process::get_arrive_time()
{
    return this->arrive_time;
} bool cmp(process A,process B)
{
    return A.get_arrive_time()<B.get_arrive_time();
} bool is_finished()
{
    if(higher_list.empty()&&middle_list.empty()&&lower_list.empty()&&process_list.empty())
        {
        return true;
        }
    return false;
}
int now_time;
void dispatch()
{
    while(true)
        {
        if(is_finished())
        {
             break;
        }
        while(true)
            {
            if(!process_list.empty()&&process_list.front().is_arrive(now_time))
                {
                process first=process_list.front();
                process_list.pop_front();
                higher_list.push_back(first);
                }
            else
                {
                break;
                }
            }
        if(!higher_list.empty())
            {
            process first=higher_list.front();
            higher_list.pop_front();
            now_time=first.run(now_time);
            }
        else if(!middle_list.empty())
            {
            process first=middle_list.front();
            middle_list.pop_front();
            now_time=first.run(now_time);
            }
        else if(!lower_list.empty())
            {
            process first=lower_list.front();
            lower_list.pop_front();
            now_time=first.run(now_time);
            }
        else
            {
            now_time++;
            }
        }
    cout<<"********************************************************************************"<<endl<<endl;
    cout<<"現在是 : "<<now_time<<"時刻,系統暫無作業,排程結束!"<<endl;
    cout<<endl<<"********************************************************************************"<<endl;
}
void init()
{
    while(!process_list.empty())
        {
        process_list.pop_front();
        }
    HIGHER_TIME_SLICE=3;
    MIDDLE_TIME_SLICE=6;
    LOWER_TIME_SLICE=12;
    process p1("A",0,10,0,READY);
    process_list.push_back(p1);
    process p2("B",1,2,0,READY);
    process_list.push_back(p2);
    process p3("C",2,3,0,READY);
    process_list.push_back(p3);
    process p4("D",3,40,0,READY);
    process_list.push_back(p4);
    process p5("E",15,2,0,READY);
    process_list.push_back(p5);
}
void user_input_model()
{
    while(!process_list.empty())
        {
        process_list.pop_front();
        }
    int p_count;
    int time_slice;
    string p_name;
    int st_time;
    int se_time;
    cout<<"***************************************************************************************"<<endl;
    cout<<setw(40)<<setfill(' ')<<left<<"請輸入要執行的程序數 : ";
    cin>>p_count;
    cout<<endl;
    cout<<setw(40)<<setfill(' ')<<left<<"請輸入要設定的第一優先佇列時間片大小 : ";
    cin>>time_slice;
    cout<<endl;
    HIGHER_TIME_SLICE =time_slice;
    cout<<setw(40)<<setfill(' ')<<left<<"請輸入要設定的第二優先佇列時間片大小 : ";
    cin>>time_slice;
    cout<<endl;
    MIDDLE_TIME_SLICE =time_slice;
    cout<<setw(40)<<setfill(' ')<<left<<"請輸入要設定的第三優先佇列時間片大小 : ";
    cin>>time_slice;
    cout<<endl;
    LOWER_TIME_SLICE =time_slice;
    for(int i=1; i<=p_count; i++)
        {
        cout<<setw(40)<<setfill(' ')<<left<<"請輸入程序名 : ";
        cin>>p_name;
        cout<<setw(40)<<setfill(' ')<<left<<"請輸入程序到達時間 : ";
        cin>>st_time;
        cout<<setw(40)<<setfill(' ')<<left<<"請輸入服務時間 : ";
        cin>>se_time;
        cout<<endl;
        process p(p_name,st_time,se_time,0,READY);
        process_list.push_back(p);
        }
    cout<<"***************************************************************************************"<<endl<<endl;
    process_list.sort(cmp);
}
int main()
{
    init();
    cout<<"即將開始"<<endl;
    cout<<"3..."<<endl;
    cout<<"2..."<<endl;
    cout<<"1..."<<endl;
    cout<<endl;
    dispatch();
    return 0;
    return 0;
}