“短進程優先”調度算法


實驗一  進程調度

一、實驗目的

    編寫並調試一個模擬的進程調度程序,以加深對進程的概念及進程調度算法的理解.

二、實驗內容

  1. 調試運行“短進程優先”調度算法,給出運行結果。
  2. 采用“短進程優先”調度算法對五個進程進行調度。每個進程有一個進程控制塊( PCB)表示。進程控制塊可以包含如下信息:進程名、到達時間、需要運行時間、已用CPU時間、進程狀態等等。
  3. 每個進程的狀態可以是就緒 W(Wait)、運行R(Run)、或完成F(Finish)三種狀態之一。 每進行一次調度程序都打印一次運行進程、就緒隊列、以及各個進程的 PCB,以便進行檢查。重復以上過程,直到所要進程都完成為止。

 

三、實現思路

 

1.  變量聲明與結構體定義

2.  輸入函數

3.  所有進程結束后,輸出所有進程信息

4.  找出運行時間最短的進程

5. 進程執行完畢

6. 主函數

 

四、主要的數據結構

1. 變量聲明與結構體定義

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

 

struct pcb{

    char name[10];    //進程名

    int arrival_time; //進程到達時間()

    int start_time;   //進程開始時間

    int need_time;      //進程運行所需時間

    int finish_time;  //運行結束時間

    struct pcb * link;   //鏈接下一個pcb的指針

};

int num = 0;     //輸入的進程數

typedef struct pcb PCB;    //定義結構體變量

/*

結構體指針p指向 每新建的一個進程

ready指針指向鏈表的第一個pcb

finish指針指向完成隊列的第一個pcb結構體

*/

struct pcb *p = NULL, *ready = NULL, *finish = NULL;

 

 

2. 輸入函數

//用來測試鏈表建立,輸入鏈表結構體數據

void print_test(){

    int i;

    struct pcb * test = ready;

    for(i=0;i<num;i++){

        printf("\n進程號:%d,進程名:%s,進程到達時間:%d,進程完成時間:%d",

                i,test->name,test->arrival_time,test->need_time);

        if(NULL != test->link){

            test = test->link;

        }

        else{

            printf("\ntest_link end\n");

        }

       

    }

}

 

 

 

//輸入函數,建立鏈表

void input(){

    int i;

    struct pcb * q;   //定義結構體變量

    printf("請輸入進程數:");

    scanf("%d", &num);

    for(i=0; i<num; i++){

        printf("\n進程號 NO.%d:", i);

        p = (struct pcb*)malloc(sizeof(struct pcb));

        printf("\n輸入進程名:");

        scanf("%s", p->name);

        printf("\n請輸入進程到達時間:");

        scanf("%d", &p->arrival_time);

        printf("\n請輸入進程運行時間:");

        scanf("%d", &p->need_time);

        

        p->link = NULL;

        //建立鏈表

        if(NULL == ready){   //建立第一個結構體,使指針p,q指向它

            ready = p;

            q = ready;

        }

        else{      //鏈表建立

            q->link = p;

            q = p;   

        }

        printf("input success");

    }

    print_test();   //測試鏈表是否建立

}

3.所有進程結束后,輸出所有進程信息

//輸出當前運行進程相關數據或者打印暫無進程運行

void output(struct pcb * p, int now_time){

    if(NULL == p){

        printf("當前時刻:%d, 暫無進程在運行!\n", now_time);

    }

    else{

        printf("進程名:%s,到達時間:%d,運行需要時間:%d\n",p->name,p->arrival_time,p->need_time);

    }

}

 

  1. 4.  找出運行時間最短的進程

//sjf  shortest job first最短作業優先

struct pcb * SJF(int now_time, int * after){

    int min_time = 0;   //最短時間,即優先運行的進程的時間

    struct pcb * now_progress = NULL, *p = ready;

    //遍歷鏈表,查找出運行時間最短的進程

    if (NULL != ready){

        while(NULL != p){

            if(now_time >= p->arrival_time){   //若進程已經到達,注意:時間單位為1

                /*

                min_time = p->need_time;      //是錯誤的

                now_progress = p;

                if(p->need_time < min_time){

                    min_time = p->need_time;

                    now_progress = p;

                } */

                if(0 == min_time){  //給最短時間賦初值

                    now_progress = p;

                    min_time = p->need_time;                   

                }

                else{

                    if(p->need_time < min_time){

                        now_progress = p;

                        min_time = p->need_time;

                    }

                }

            }

            p = p->link;

        }

    }

    *after = min_time + now_time;

    printf("\nSJF:a shortest progress running!\n");

    return now_progress;   //返回指向正在運行進程的指針

}

 

5. 進程執行完畢

//將已經運行完成的進程添加到finish隊列,並且進程數減一

void destory(struct pcb * p, int now_time){

    printf("destory start!\n");

    struct pcb * q = ready;

    struct pcb * f = NULL;   //用於finish鏈表的添加

 

   

    if(strcmp(p->name, ready->name) == 0){  //若第一個進程完成

        ready = ready->link;

    }

    //若中間或最后一個進程完成

    else{

        q = ready;

        while((strcmp(q->link->name,p->name) != 0) && NULL != q->link){

            q = q->link;

        }

        q->link = p->link;

    }

   

     p->finish_time = now_time;    //結束時間

     p->start_time =  now_time - p->need_time;  //開始時間

    

    //將已經運行的進程添加到finish隊列

    if(NULL == finish){

        finish = p;    //finish指向完成鏈表的表頭

        p->link = NULL;

    }

    else{

        f = finish;

        while(NULL != f->link){

            f = f->link;

        }

        f->link = p;

        p->link = NULL;

    }

   

    num--;   //進程數減一

    printf("\ndestory success!\n");

}

主函數

int main(int argc, char *argv[]) {

   

   

    input();  //調用輸入函數

   

    int now_time = 0;    //初始時間為0

    int after = 0;        //執行完一個進程后的時間:優先運行進程的運行時間+當前時間

    struct pcb * now_progress = NULL;    //now_progress指向正在運行的進程(結構體)

    struct pcb *m = NULL;

   

    while(num > 0){    //進程數大於0,每次循環num會減一

        printf("start SJF");

        now_progress = SJF(now_time, &after);  //調用SJF函數,遍歷鏈表

 

       

        if(NULL != now_progress){

            /*進程執行,每循環一次,當前時間加一

              同時要判斷當前時間是否有進程剛好到達正在在等待 */

            for(;now_time < after; now_time++){

                printf("\n當前時刻:%d", now_time);

                printf("\n-----------當前執行進程------------\n");

                output(now_progress, now_time);     //調用output函數

                printf("\n-----------等待執行進程------------\n");

               

                m = ready;

                while(NULL != m){   //循環,若當前時間有進程到達,打印相關信息

                    if(m != now_progress){

                        if(m->arrival_time <= now_time){

                            output(m, now_time);

                            printf("\na new progress arrival\n");

                        }

                    }

                    m = m->link;

                }

            }

            //進程執行完后調用destory函數

            destory(now_progress, now_time);

 

        }

        else{   //沒有進程在運行

            output(now_progress, now_time);

            now_time++;

        }

       

    }

    output_all();

    return 0;

   

}

五、算法流程圖

 

 

 

六、運行與測試(系統運行截圖)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

七、總結

 

SJF算法是以進程的運行時間長度作為優先級,進程運行時間越短,優先級越高。

缺點

必須預知進程的運行時間。即使是程序員也很難准確估計進程運行時間。如果估計過低,系統就可能按估計的時間終止進程的運行,但此時進程並未完成,故一般都會偏長估計

對長進程不利。長進程的周轉時間會明顯地增長。可怕的是,SJF算法完全忽視進程等待時間,可能使進程等待時間過長,出現飢餓現象。

人機無法實現交互。

完全未考慮進程的緊迫程度。不能保證緊迫性進程得到及時處理。

 

 

問題:對比說明短進程優先和動態優先數中PCB的定義有什么不同?


免責聲明!

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



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