一、實驗目的
用高級語言完成一個進程調度程序,以加深對進程的概念及進程調度算法的理解。
二、實驗內容和要求
設計一個有 N個進程並發執行的進程調度模擬程序。
進程調度算法:采用最高優先級優先的調度算法(即把處理機分配給優先級最高的進程)和先來先服務(若優先級相同)算法。動態優先數是指進程的優先數在創建進程時可以給定一個初始值,並且可以按一定規則修改優先數。例如:在進程獲得一次CPU后就將其優先數減少1,並且進程等待的時間超過某一時限(2個時間片時間)時增加其優先數等。
(1). 每個進程有一個進程控制塊(PCB)表示。進程控制塊包含如下信息:進程名、優先級、到達時間、需要運行時間、已用CPU時間、進程狀態等等。
(2). 進程的優先級及需要的運行時間可以事先人為地指定,進程的運行時間以時間片為單位進行計算。
(3). 每個進程的狀態可以是就緒 r(ready)、運行R(Running)、或完成F(Finished)三種狀態之一。
(4). 就緒進程獲得 CPU后都只能運行一個時間片。用已占用CPU時間加1來表示。
(5). 如果運行一個時間片后,進程的已占用 CPU時間已達到所需要的運行時間,則撤消該進程,如果運行一個時間片后進程的已占用CPU時間還未達所需要的運行時間,也就是進程還需要繼續運行,此時應將進程的優先數減1(即降低一級),然后把它插入就緒隊列等待調度。
(6). 每進行一次調度程序都打印一次運行進程、就緒隊列中各個進程的 PCB,以便進行檢查。
(7). 重復以上過程,直到所要進程都完成為止。
三、實驗方法、步驟及結果測試
1. 源程序名:壓縮包文件(rar或zip)中源程序名實驗三zy.c
可執行程序名:實驗三 zy.exe
2.原理分析及流程圖
存儲結構:用結構體數據類型表示一個進程,結構體成員包括:進程到達系統時間arrivetime,運行時間needtime,優先級 priority已占用cpu時間 usetime
3.主要程序段及其解釋:
#include<stdio.h> #include<string.h> void arrivesort(struct pcb pcbs[10],int n); void result(struct pcb pcbs[10],int n); void prioritysort(struct pcb pcbs[10],int n); struct pcb{ char name[10]; int priority; //進程優先級 int arrivetime; //進程到達時間 int needtime; //進程需要運行時間 int usetime; //進程已占用cpu時間 }; void main() { struct pcb pcbs[10]; int n,i; //n個進程 printf("輸入進程個數:",n); scanf("%d",&n); printf("輸入每個進程的進程名,優先級,到達時間,運行時間:\n"); for(i=0;i<n;i++) { scanf("%s",pcbs[i].name); scanf("%d",&pcbs[i].priority); scanf("%d",&pcbs[i].arrivetime); scanf("%d",&pcbs[i].needtime); pcbs[i].usetime=0; } for(i=0;i<n;i++) { prioritysort(pcbs,n); arrivesort(pcbs,n); pcbs[i].usetime++; printf("\n"); printf("動態優先級調度進程運行順序:\n"); result(pcbs,n); pcbs[i].priority--; pcbs[i].usetime++; } } void arrivesort(struct pcb pcbs[10],int n) { int i=0; char temp[10]; int min; for(i=0;i<n-1;i++) { if(pcbs[i].arrivetime>pcbs[i+1].arrivetime) { min=pcbs[i].arrivetime; pcbs[i].arrivetime=pcbs[i+1].arrivetime; pcbs[i+1].arrivetime=min; min=pcbs[i].needtime; pcbs[i].needtime=pcbs[i+1].needtime; pcbs[i+1].needtime=min; min=pcbs[i].priority; pcbs[i].priority=pcbs[i+1].priority; pcbs[i+1].priority=min; strcpy(temp,pcbs[i].name); strcpy(pcbs[i].name,pcbs[i+1].name); strcpy(pcbs[i+1].name,temp); } } //按進程到達系統時間進行排序,最早到達的排在最前面 } void result(struct pcb pcbs[10],int n) { int i; printf("進程名\t優先級\t到達時間\t運行時間\t已占用cpu時間\n"); for(i=0;i<n;i++) { printf("%s\t %d\t %d\t %d\t %d\n",pcbs[i].name,pcbs[i].priority,pcbs[i].arrivetime,pcbs[i].needtime,pcbs[i].usetime); } } void prioritysort(struct pcb pcbs[10],int n) { int i=0; char temp[10]; int min; for(i=0;i<n;i++) { if(pcbs[i].priority<pcbs[i+1].priority) { min=pcbs[i].priority; pcbs[i].priority=pcbs[i+1].priority; pcbs[i+1].priority=min; min=pcbs[i].arrivetime; pcbs[i].arrivetime=pcbs[i+1].arrivetime; pcbs[i+1].arrivetime=min; min=pcbs[i].needtime; pcbs[i].needtime=pcbs[i+1].needtime; pcbs[i+1].needtime=min; strcpy(temp,pcbs[i].name); strcpy(pcbs[i].name,pcbs[i+1].name); strcpy(pcbs[i+1].name,temp); // pcbs[i].usetime++; } //按進程優先級排序,最高的排在最前面 } }
4.運行結果及分析
算法仍然存在瑕疵,主要的算法思想是先按照進程優先級排序,再按照到達時間排序選擇最高優先級的進程運行一個時間片(例如時間片為1),所對應進程占用cpu的時間加1,相應的優先級減1,再按照優先級從高到低排序,選擇最高優先級進程調度,如果兩進程優先級相同,則按照先來先服務算法,先到達的先調度。
四、實驗總結
實驗從字面容易理解,但實踐過程中還是相當有難度,但經過老師的講解和同學的幫助,算是勉強完成,今后需多加努力。