1. 程式人生 > >程序排程的設計與實現——實驗報告

程序排程的設計與實現——實驗報告

程序排程的設計與實現

中文摘要

       無論是在批處理系統還是分時系統中,使用者程序數一般都多於處理機數、這將導致它們互相爭奪處理機。另外,系統程序也同樣需要使用處理機。這就要求程序排程程式按一定的策略,動態地把處理機分配給處於就緒佇列中的某一個程序,以使之執行。

關鍵詞

程序排程 C++ 優先順序 生命週期 pid status

前言

實驗目的

1、綜合應用下列知識點設計並實現作業系統的程序排程:鄰接表,布林陣列,非阻塞輸入,圖形使用者介面GUI,程序控制塊,程序狀態轉換,多級反饋佇列程序排程演算法。

2、加深理解作業系統程序排程的過程。

3、加深理解多級反饋佇列程序排程演算法。

實驗內容與主要設計思想

1、採用一種熟悉的語言,如 C、 PASCAL 或 C++等,編制程式,最好關鍵程式碼採用 C/C++,介面設計可採用其它自己喜歡的語言。

2、採用多級反饋佇列排程演算法進行程序排程。

3、每個程序對應一個 PCB。在 PCB 中包括程序識別符號 pid、程序的狀態標識 status、程序優先順序 priority、程序的佇列指標 next 和表示程序生命週期的資料項 life(在實際系統中不包括該項)。

4、建立程序時即建立一個 PCB,各個程序的 pid 都是唯一的, pid 是在 1到 100 範圍內的一個整數。可以建立一個下標為 1 到 100 的布林陣列,“真”表示下標對應的程序標識號是空閒的,“假”表示下標對應的程序標識號已分配給某個程序。

5、程序狀態 status 的取值為“就緒 ready”或“執行 run”,剛建立時,狀態為“ ready”。被程序排程程式選中後變為“ run”。

6、程序優先順序 priority 是 0 到 49 範圍內的一個隨機整數。

7、程序生命週期 life 是 1 到 5 範圍內的一個隨機整數。

8、初始化時,建立一個鄰接表,包含 50 個就緒佇列,各就緒佇列的程序優先順序 priority 分別是 0 到 49。

9、為了模擬使用者動態提交任務的過程,要求動態建立程序。進入程序排程迴圈後,每次按 ctrl+f即動態建立一個程序,然後將該PCB 插入就緒佇列中。按 ctrl+q 退出程序排程迴圈。

10、在程序排程迴圈中,每次選擇優先順序最大的就緒程序來執行。將其狀態從就緒變為執行,通過延時一段時間來模擬該程序執行一個時間片的過程,然後優先順序減半,生命週期減一。設計圖形使用者介面 GUI,在視窗中顯示該程序和其他所有程序的 PCB 內容。如果將該執行程序的生命週期不為 0,則重新把它變為就緒狀態,插入就緒佇列中;否則該程序執行完成,撤消其 PCB。以上為一次程序排程迴圈。

流程圖

實驗實現

實驗平臺

硬體:

    CPU:Intel Core i5-8250u

    RAM:ddr4 8g

    SSD:Sansung pm961 256g

軟體:

    OS:deepin 15.5

    IDE:Qt 5.8.0

主要功能模組分析

建立程序

void PCB_adjlist::ctreat_pcb() {   //根據指令建立程序
    PCB *newpcb=new PCB;
    newpcb->priority = qrand()%50;  //優先順序0-49
    newpcb->life = qrand()%5+1;     //生命週期1-5
    newpcb->status = true;          //就緒狀態
    while (true) {
        int x = qrand()%100+1;      //程序識別符號1-100
        if (judge_empty(x - 1)) {
            newpcb->pid = x;
            break;
        }
    }
    int numpri = newpcb->priority;
    PCB *p = list[numpri].next;
    if (p != NULL) {
        while (p->next != NULL) {
            p = p->next;
        }
        p->next = newpcb;   //插到隊尾
    }
    else {
        list[numpri].next = newpcb;
    }
}

執行程序

void PCB_adjlist::run_pcb() {   //執行pcb
    int top_pcb=-1;   //記錄需最先執行的pcb指標
    for (int i = 49; i >=0; i--) {
        if (list[i].next != NULL) {
            top_pcb = i;
            break;
        }
    }
    if (top_pcb == -1)  //如果無可執行的pcb,返回
        return;
    PCB *p = list[top_pcb].next,*q;  //建立兩個指標,*q用來進行刪除操作
    p->status = 0;  //改為執行狀態
    if (p->life == 1) {  //若生命週期為1,則執行完刪除
        q = p->next;
        list[top_pcb].next = q;
        delete p;
    }
    else {
        q = p->next;
        list[top_pcb].next = q; //指向下一程序
        p->status = 1;  //就緒狀態
        p->life--;
        int top_pri = p->priority;
        top_pri /= 2;   //優先順序減半
        p->priority = top_pri;
        p->next = NULL;
        PCB *newpcb = list[top_pri].next;
        if (newpcb == NULL) {   //插入新優先順序佇列
            list[top_pri].next = p;
        }
        else {
            while (newpcb->next != NULL)
                newpcb = newpcb->next;
            newpcb->next = p;
        }
    }
    return;
}、

快捷鍵設定

newAction = new QAction("New PCB",this);
this->newAction->setShortcut(tr("ctrl+f")); //快捷鍵

定時執行

QObject::connect(timer, SIGNAL(timeout()), this, SLOT(slotRun()));  //設定定時執行
void MainWindow::slotStart()
{
    timer->start(1000); //開始定時執行函式,時間間隔為1s
}

實驗結果

截圖