操作系統實驗三(進程調度之優先數與時間片)


. 實驗目的

  理解進程運行的並發性

    理解進程各種狀態及其之間的轉換 

   理解進程管理中PCB的結構

         掌握優先數進程調度算法

. 實驗內容

    VC編寫實現進程調度算法模擬進程調度的實現過程。調度算法采用的是動態優先數與時間片相結合的算法。要求如下

  • 進程相關信息如進程標識符及進程所需時間都放入PCB中;
  • 設計運行、完成和就緒三個進程隊列;
  • 就緒隊列按優先數從小到大排列,每次選擇優先數最大的就緒進程運行。初始優先數定為用一個較大的數(如30)減去進程運行時間,隨着進程的運行對優先數進行調整;
  • 進程每執行一次,優先數減一個固定值(如3),CPU時間加1,進程所需時間減1.如果進程所需時間變為0,說明進程運行完畢,將其狀態置為"F",將其PCB插入到完成隊列中,此時若就緒隊列不空,則將就緒隊列的第一個PCB變為運行狀態。 如果進程未完成,則將其優先數和就緒隊列中第一個PCB優先數比較,如果小,則將其變為就緒態,插入就緒隊列中適當位置,同時將就緒隊列中第一個PCB變為運行態。重復上述過程直到就緒隊列為空,所有進程成為完成狀態。

    相關數據結構:

          typedef struct node{ 

                 char name[10];       //進程標識符

                 int prio;        //進程優先級

                 int cput;       //進程占用的CPU時間

                 int needt;            //進程離完成還需要的CPU時間

                char state;         //進程狀態 struct node *next;

        }PCB;

 

三、實驗代碼

     參考實驗二中的代碼自行完成該算法代碼。

要求:

   編寫算法實現的流程圖

   編程實現題目要求的功能

   測試多組數據的實驗結果

#include <iostream>
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <bits/stdc++.h> 
using namespace std;
//定義動態申請空間的函數 
#define getpch(type) (type*)malloc(sizeof(type))
typedef struct node {
    int ID;//進程的標識符 
    int prio;//進程的優先級 
    int cput;//進程占用的CPU時間 
    int ncput;//進程離完成還需要的CPU時間 
    char state;//進程的狀態 R運行,W等待,在run中使用F-T。 
    struct node *next;
}PCB;
PCB *ready, *run, *finish;//准備,運行,完成。 
void InitProcess();//進程的初始化設置
void insertByDesc(PCB *p);//插入節點,按照從大到小排序(優先級高的先運行) 
void printreadyinfo();//輸出就緒隊列的信息
void processrunning();//進程開始運行 
void JoinCPU();//從進程中選取一個進程進入CPU開始運行
void showrun(PCB *p);//顯示正在運行的進程(顯示過程) 
void showfinish(PCB *p);//顯示完成的信息 
void setfinish(PCB *p);////進程完成,設置為完成
//主函數 
int main() {
    run = getpch(PCB);//申請節點空間 
    finish =getpch(PCB);
    ready = getpch(PCB);
    ready->next = NULL;
    run->next = NULL;
    finish->next = NULL;
    InitProcess();//初始化進程 
    processrunning();
    return 0;
}
void showrun(PCB *p) {
    printf("進程運行的信息:\n");
    cout<<"ID"<<"   "<<"Prio"<<"   "<<"cput"<<"   "<<"ncput"<<"   "<<"state"<<endl;
    printf("%-4d %-7d %-7d %-7d %-7c\n", p->ID, p->prio, p->cput, p->ncput, p->state);
}
void showfinish(PCB *p) {
    printf("完成的進程信息:\n");
    cout<<"ID"<<"   "<<"Prio"<<"   "<<"cput"<<"   "<<"ncput"<<"   "<<"state"<<endl;
    printf("%-4d %-7d %-7d %-7d %-7c\n", p->ID, p->prio, p->cput, p->ncput, p->state);
}
//進程完成,設置為完成 
void setfinish(PCB *p) {
    PCB *r;
    if (p->ncput == 0) {//如果運行所需時間為0,放入finish
        r = finish;
        while (r->next != NULL) {
            r = r->next;
        }
        p->state = 'F';//將當前進程置為完成狀態
        p->next = r->next;
        r->next = p;
        showfinish(p);//輸出完成的信息 
    }
}
//從進程中選取一個進程進入CPU開始運行 
void JoinCPU() {
    if (ready->next != NULL) {//如果就緒隊列不為空,第一個PCB置運行
        run->next = ready->next;//開始運行 
        ready->next = ready->next->next;//第一個從就緒隊列刪除
        run->next->state = 'R';//運行的進程狀態改為R 
        run->next->prio -= 3;//每進入CPU一次優先級-3 
        run->next->cput += 1;//CPU占用的時間+1 
        run->next->ncput -= 1;//一共還需要的時間-1 
    }
}
void processrunning() {
    JoinCPU();
    setfinish(run->next);//時間為零置finish
    if (run->next->state != 'F')
        showrun(run->next);
    while (1) {
        if (ready->next != NULL && run->next->prio < ready->next->prio) { //小於第一個PCB優先數就將其插入就緒並調用下一個進程
            if (run->next->state != 'F')//如果進程已完成就不用插入就緒
                insertByDesc(run->next);//重新進行排序 
            JoinCPU();
            setfinish(run->next);
            if (run->next->state != 'F')
                showrun(run->next);
 
        }
        else
        {
            run->next->prio -= 3;
            run->next->cput += 1;
            run->next->ncput -= 1;
            setfinish(run->next);
            if (run->next->state != 'F')
                showrun(run->next);
            if (ready->next == NULL) {
                break;
            }
 
        }
    }
}
//輸出就緒隊列的信息 
void printreadyinfo() {
    PCB *p;
    p = ready->next;
    cout<<"就緒進程的信息(ready info)"<<endl;
    cout<<"ID"<<"   "<<"Prio"<<"   "<<"cput"<<"   "<<"ncput"<<"   "<<"state"<<endl;
    while (p != NULL) {
        printf("%-4d %-7d %-7d %-7d %-7c\n", p->ID, p->prio, p->cput, p->ncput, p->state);
        p = p->next;
    }
}
//插入節點,按照從大到小排序(優先級高的先運行) 
void insertByDesc(PCB *p){
    PCB *tmp;
    tmp = ready;
    while (tmp->next != NULL && tmp->next->prio >= p->prio) {//從大到小排序
        tmp = tmp->next;
    }
    //第一個節點 
    p->next = tmp->next;
    tmp->next = p;
}
//進程狀態的初始化: 
void InitProcess() {
    PCB *p;
    int n;
    printf("情輸入進程的個數:");
    cin>>n;//輸入了進程的個數; 
    cout<<"請輸入進程的標識符和程占用的CPU時間"<<endl; 
    for (int i = 1; i <= n; i++) {
        p = getpch(PCB);
        int id, pri, needt;//設置變量,進程的標識,優先級,占用CPU的時間。 
        cin>>id>>needt;
        p->ID = id;
        p->prio = 30;//優先級初始狀態為30 
        p->cput = 0;//初始化時還未占用CPU 
        p->ncput = needt;//一共需要的CPU時間 
        p->state = 'w';//狀態等待。 
        insertByDesc(p);
    }
    printreadyinfo(); 
}

 

  

 

 

 

 

 

 

 

 

 

 

 

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM