1. 目的和要求
用高級語言完成一個進程調度程序,以加深對進程的概念及進程調度算法的理解。
實驗要求
設計一個有 N(N不小於5)個進程並發執行的進程調度模擬程序。
進程調度算法:“時間片輪轉法”調度算法對N個進程進行調度。
2. 實驗內容
完成兩個算法(簡單時間片輪轉法、多級反饋隊列調度算法)的設計、編碼和調試工作,完成實驗報告。
1) 每個進程有一個進程控制塊(PCB)表示。進程控制塊包含如下信息:進程名、優先級、到達時間、需要運行時間、已用CPU時間、進程狀態等等。
2) 每個進程的狀態可以是就緒 r(ready)、運行R(Running)、或完成F(Finished)三種狀態之一。
3) 就緒進程獲得 CPU后都只能運行一個時間片。用已占用CPU時間加1來表示。
4) 如果運行一個時間片后,進程的已占用 CPU時間已達到所需要的運行時間,則撤消該進程,如果運行一個時間片后進程的已占用CPU時間還未達所需要的運行時間,也就是進程還需要繼續運行,應把它插入就緒隊列等待下一次調度。
5) 每進行一次調度,程序都打印一次運行進程、就緒隊列中各個進程的 PCB,以便進行檢查。
3. 實驗原理及核心算法
“輪轉法”有簡單輪轉法、多級反饋隊列調度算法。
(1). 簡單輪轉法的基本思想是:
所有就緒進程按 FCFS排成一個隊列,總是把處理機分配給隊首的進程,各進程占用CPU的時間片長度相同。如果運行進程用完它的時間片后還未完成,就把它送回到就緒隊列的末尾,把處理機重新分配給隊首的進程。直至所有的進程運行完畢。
(2). 多級反饋隊列調度算法的基本思想是:
將就緒隊列分為N級(N=3~5),每個就緒隊列優先數不同並且分配給不同的時間片:隊列級別越高,優先數越低,時間片越長;級別越小,優先數越高,時間片越短。
系統從第一級調度,當第一級為空時,系統轉向第二級隊列,.....當處於運行態的進程用完一個時間片,若未完成則放棄CPU,進入下一級隊列。
當進程第一次就緒時,進入第一級隊列。
4. 實驗環境
自主選擇實驗環境。可以選用Turbo C作為開發環境。也可以選用Windows下的可視化環境,利用各種控件較為方便。
5. 源代碼
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 100
typedef struct
{
char name[4];//進程名
int priority;//優先級
int starttime;//到達系統時間
int needtime;//運行時間
int cputime;//已用CPU時間
char state;//進程狀態
}pr;
pr a[MAX];
int n;//進程數
int t;//時間片大小
void input()
{
int i;
printf("請輸入進程的名字,優先級,到達系統時間,運行時間:\n");
for(i=0;i<n;i++)
{
scanf("%s",&a[i].name);
scanf("%d",&a[i].priority);
scanf("%d",&a[i].starttime);
scanf("%d",&a[i].needtime);
a[i].cputime=0;
a[i].state='W';
}
}
void Sort()
{
int i,j;
pr temp;
for(i=0;i<n-1;i++) //先按到達系統時間排序
{
for(j=0;j<n-1-i;j++)
if(a[j].starttime>a[j+1].starttime)
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
for(i=0;i<n-1;i++) //再按優先級排序,數字高則優先級高
{
for(j=0;j<n-1-i;j++)
if(a[j].priority<a[j+1].priority)
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
if (a[0].state!='F')
{
a[0].state='R';
//將優先級最高的狀態置為運行
}
}
void output()
{
int i;
Sort();//先排好序再打印輸出
printf("\t進程名 優先級 到達時間 運行時間 已用時間 進程狀態 \n");
for(i=0;i<n;i++)
{
printf("%8s%10d%10d%10d%10d%10c\n",a[i].name,a[i].priority,a[i].starttime,a[i].needtime,a[i].cputime,a[i].state);
}
printf("\n\n");
}
void RR()
{
//每次運行進程只針對排好序后的第一個進程即第0號元素
//當第一個進程運行完一個時間片優先級減一后再對進程進行按到達系統時間
//和優先級排序,所以實現了根據優先級的時間片輪轉執行進程
do{
if((a[0].needtime-a[0].cputime)>t)//若剩余時間大於時間片
{
a[0].cputime+=t;
a[0].priority--;//優先級減一
a[0].state='W';//執行完一個時間片后變為等待狀態}//已用時間加上時間片
}
else
{
a[0].cputime=a[0].needtime;//已用時間等於運行時間
a[0].priority=-10000;//優先級為-10000,表示完成進程
a[0].state='F';
}
output();//打印結果,函數內部含有排序算法
} while(a[0].state!='F');
}
int main()
{
printf("請輸入進程數n:");
scanf("%d",&n);
printf("\n");
printf("請輸入時間片大小t:");
scanf("%d",&t);
printf("\n");
input();
output();//輸入進程按排序后顯示,函數內部含有排序算法
RR();
}
6. 實驗結果
7. 結論
由於個人問題,實驗三自己做的話不能夠做出來,所以我去借鑒了同學的代碼,在其基礎上修改了一些代碼,總體上還是能勉強過得去.但畢竟自己做的少,印象也沒那么深刻,所以我明白了實驗需要自己動手做,這樣才能體會其中的苦樂,學到的更多.