1.實驗目的和要求
1.1. 實驗目的
用高級語言完成一個進程調度程序,以加深對進程的概念及進程調度算法的理解。
1.2.實驗要求
1.2.1例題:設計一個有 N個進程並發執行的進程調度模擬程序。
進程調度算法:采用最高優先級優先的調度算法(即把處理機分配給優先級最高的進程)和先來先服務(若優先級相同)算法。
(1). 每個進程有一個進程控制塊(PCB)表示。進程控制塊包含如下信息:進程名、優先級、到達時間、需要運行時間、已用CPU時間、進程狀態等等。
(2). 進程的優先級及需要的運行時間可以事先人為地指定,進程的運行時間以時間片為單位進行計算。
(3). 每個進程的狀態可以是就緒 r(ready)、運行R(Running)、或完成F(Finished)三種狀態之一。
(4). 就緒進程獲得 CPU后都只能運行一個時間片。用已占用CPU時間加1來表示。
(5). 如果運行一個時間片后,進程的已占用 CPU時間已達到所需要的運行時間,則撤消該進程,如果運行一個時間片后進程的已占用CPU時間還未達所需要的運行時間,也就是進程還需要繼續運行,此時應將進程的優先數減1(即降低一級),然后把它插入就緒隊列等待調度。
(6). 每進行一次調度程序都打印一次運行進程、就緒隊列中各個進程的 PCB,以便進行檢查。
(7). 重復以上過程,直到所要進程都完成為止。
思考:作業調度與進程調度的不同?
1.2.2實驗題A:編寫並調試一個模擬的進程調度程序,采用“最高優先數優先”調度算法對N(N不小於5)個進程進行調度。
“最高優先級優先”調度算法的基本思想是把CPU分配給就緒隊列中優先數最高的進程。
(1). 靜態優先數是在創建進程時確定的,並在整個進程運行期間不再改變。
(2). 動態優先數是指進程的優先數在創建進程時可以給定一個初始值,並且可以按一定規則修改優先數。例如:在進程獲得一次CPU后就將其優先數減少1,並且進程等待的時間超過某一時限(2個時間片時間)時增加其優先數等。
(3). (**) 進程的優先數及需要的運行時間可以事先人為地指定,(也可以由隨機數產生)。
(4). (**)在進行模擬調度過程可以創建(增加)進程,其到達時間為進程輸入的時間。
1.2.3實驗題B:編寫並調試一個模擬的進程調度程序,采用“基於時間片輪轉法”調度算法對N(N不小於5)個進程進行調度。 “輪轉法”有簡單輪轉法、多級反饋隊列調度算法。
(1). 簡單輪轉法的基本思想是:所有就緒進程按 FCFS排成一個隊列,總是把處理機分配給隊首的進程,各進程占用CPU的時間片長度相同。如果運行進程用完它的時間片后還未完成,就把它送回到就緒隊列的末尾,把處理機重新分配給隊首的進程。直至所有的進程運行完畢。(此調度算法是否有優先級?)
(2). 多級反饋隊列調度算法的基本思想是:
將就緒隊列分為N級(N=3~5),每個就緒隊列優先數不同並且分配給不同的時間片:隊列級別越高,優先數越低,時間片越長;級別越小,優先數越高,時間片越短。
系統從第一級調度,當第一級為空時,系統轉向第二級隊列,.....當處於運行態的進程用完一個時間片,若未完成則放棄CPU,進入下一級隊列。
當進程第一次就緒時,進入第一級隊列。
(3). (**)考慮進程的阻塞狀態B(Blocked)增加阻塞隊列。進程的是否阻塞和阻塞的時間由產生的“隨機數”確定(阻塞的頻率和時間長度要較為合理)。注意進程只有處於運行狀態才可能轉換成阻塞狀態,進程只有處於就緒狀態才可以轉換成運行狀態。
2.實驗內容
根據指定的實驗課題:A(1),A(2),B(1)和B(2)
完成設計、編碼和調試工作,完成實驗報告。
注:帶**號的條目表示選做內容。
3. 實驗環境
可以選用Turbo C作為開發環境。也可以選用Windows下的VB,CB等可視化環境,利用各種控件較為方便。自主選擇實驗環境。
4.實驗原理及核心算法參考程序段
動態優先數(優先數只減不加):
源代碼:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #define Max 100 5 typedef struct pcb 6 { 7 char name[Max]; //進程名 8 int priority; //優先級 9 int arrtime; //到達時間 10 int needtime; //需要運行時間 11 int usedtime; //已用時間 12 char state; //進程狀態 13 }PCB; 14 PCB pcb[Max]; 15 16 int n=1; 17 int pTime; //時間片 18 char SelectMenu(); 19 void Input(); 20 void Sort(); 21 void Print(); 22 void Attemper(); 23 24 char SelectMenu() 25 { 26 char select; 27 printf("功能菜單:"); 28 printf("\n 1.增加並調度進程"); 29 printf("\n 2.打印進程"); 30 printf("\n 3.退出"); 31 printf("\n請輸入你的選擇(1--3):"); 32 do{ 33 select=getchar(); 34 }while(select!='1'&&select!='2'&&select!='3'); 35 return select; 36 } 37 38 void main() 39 { 40 int choice; 41 n=1; 42 printf(" \n"); 43 printf("\t\t歡迎使用進程調度模擬\n\n"); 44 choice=SelectMenu(); 45 do{ 46 if(choice=='1') 47 { 48 printf(" \n"); 49 printf("請設置時間片的大小:"); 50 scanf("%d",&pTime); 51 Input(); 52 Print(); 53 Attemper(); 54 } 55 if(choice=='2') 56 { 57 Print(); 58 } 59 if(choice=='3') 60 { 61 return; 62 } 63 choice=SelectMenu(); 64 }while(1); 65 } 66 67 void Input() 68 { 69 do{ 70 printf("\n---請輸入第%d個進程進程---\n",n); 71 printf("\n進程名:"); 72 scanf("%s",pcb[n].name); 73 printf("進程優先級:"); 74 scanf("%d",&pcb[n].priority); 75 printf("進程需要的時間:"); 76 scanf("%d",&pcb[n].needtime); 77 pcb[n].arrtime=n; 78 pcb[n].usedtime=0; 79 pcb[n].state='W'; 80 n++; 81 }while(n<5); 82 } 83 84 void Sort() 85 { 86 int i,j; 87 PCB temp; 88 for(i=0;i<n-1;i++) //按照到達時間排序 89 { 90 for(j=n-2;j>=i;j--) 91 { 92 if(pcb[j+1].arrtime<pcb[j].arrtime) 93 { 94 temp=pcb[j]; 95 pcb[j]=pcb[j+1]; 96 pcb[j+1]=temp; 97 } 98 } 99 } 100 101 for(i=0;i<n-1;i++) //按照優先級排序 102 { 103 for(j=n-2;j>=i;j--) 104 { 105 if(pcb[j+1].priority>pcb[j].priority) 106 { 107 temp=pcb[j]; 108 pcb[j]=pcb[j+1]; 109 pcb[j+1]=temp; 110 } 111 } 112 } 113 if(pcb[0].state!='F') 114 { 115 pcb[0].state='R'; 116 } 117 } 118 119 void Print() 120 { 121 int i; 122 Sort(); 123 printf("\n 進程名 優先級 到達時間 需要時間 已用時間 進程狀態 \n"); 124 for(i=0;i<n;i++) 125 { 126 printf("%8s%8d %8d %10d %10d %10c\n",pcb[i].name,pcb[i].priority,pcb[i].arrtime,pcb[i].needtime,pcb[i].usedtime,pcb[i].state); 127 } 128 } 129 130 void Attemper() 131 { 132 do{ 133 if((pcb[0].needtime-pcb[0].usedtime)>pTime) //判斷進程剩余的運行時間是否大於時間片 134 { 135 pcb[0].usedtime+=pTime; 136 pcb[0].priority--; 137 pcb[0].state='W'; 138 } 139 else //已完成的進程 140 { 141 pcb[0].usedtime=pcb[0].needtime; 142 pcb[0].priority=-1; 143 pcb[0].state='F'; 144 } 145 Print(); 146 }while(pcb[0].state!='F'); 147 }
運行結果: