實驗三 進程調度模擬程序
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. 實驗原理及核心算法參考程序段
動態優先數(優先數只減不加):
源程序:
#include"stdio.h"
#include"stdlib.h"
#include"string.h"
typedef struct node
{
char name[10]; //進程標志符
int prio; //進程優先數
int cputime; //進程占用cpu時間
int needtime; //進程到完成還要的時間
char state; //進程的狀態
struct node *next; //鏈指針
}PCB;
PCB *finish,*ready,*tail,*run; //隊列指針
int N; //進程數
//將就緒隊列的第一個進程投入運行
firstin()
{
run=ready; //就緒隊列頭指針賦值給運行頭指針
run->state='R'; //進程狀態變為運行態
ready=ready->next; //就緒列頭指針后移到下一進程
}//標題輸出函數
void prt1(char a)
{
printf("進程號 cpu時間 所需時間 優先數 狀態\n");
}
//進程PCB輸出
void prt2(char a,PCB *q)
{ //優先數算法輸出
printf(" % -10s% -10d% -10d% -10d %c\n",q->name,q->cputime,q->needtime,q->prio,q->state);
}
//輸出函數
void prt(char algo)
{
PCB *p;
prt1(algo); //輸出標題
if(run!=NULL) //如果運行標題指針不空
prt2(algo,run); //輸出當前正在運行的PCB
p=ready; //輸出就緒隊列PCB
while(p!=NULL)
{
prt2(algo,p);
p=p->next;
}
p=finish; //輸出完成隊列的PCB
while(p!=NULL)
{
prt2(algo,p);
p=p->next;
}
getchar(); //按任意鍵繼續
}
//優先數的算法插入算法
insert1(PCB *q)
{
PCB *p1,*s,*r;
int b;
s=q; //待插入的PCB指針
p1=ready; //就緒隊列頭指針
r=p1; //r做p1的前驅指針
b=1;
while((p1!=NULL)&&b) //根據優先數確定插入位置
if(p1->prio>=s->prio)
{
r=p1;
p1=p1->next;
}
else
b=0;
if(r!=p1) //如果條件成立說明插入在r與p1之間
{
r->next=s;
s->next=p1;
}
else
{
s->next=p1; //否則插入在就緒隊列的頭
ready=s;
}
}
//優先數創建初始PCB信息
void create1(char alg)
{
PCB *p;
int i,time;
char na[10];
ready=NULL; //就緒隊列頭文件
finish=NULL; //完成隊列頭文件
run=NULL; //運行隊列頭文件
printf("輸入進程號和運行時間:\n"); //輸入進程標志和所需時間創建PCB
for(i=1;i<=N;i++)
{
p=(PCB *)malloc(sizeof(PCB));
scanf("%s",na);
scanf("%d",&time);
strcpy(p->name,na);
p->cputime=0;
p->needtime=time;
p->state='w';
p->prio=50-time;
if(ready!=NULL) //就緒隊列不空,調用插入函數插入
insert1(p);
else
{
p->next=ready; //創建就緒隊列的第一個PCB
ready=p;
}
}
//clrscr();
printf(" 優先數算法輸出信息:\n");
printf("***********************************************\n");
prt(alg); //輸出進程PCB信息
run=ready; //將就緒隊列的第一個進程投入運行
ready=ready->next;
run->state='R';
}
//優先數調度算法
void priority(char alg)
{
while(run!=NULL) //當運行隊列不空時,有進程正在運行
{
run->cputime=run->cputime+1;
run->needtime=run->needtime-1;
run->prio=run->prio-3; //每運行一次優先數降低3個單位
if(run->needtime==0) //如所需時間為0將其插入完成隊列
{
run->next=finish;
finish=run;
run->state='F'; //置狀態為完成態
run=NULL; //運行隊列頭指針為空
if(ready!=NULL) //如就緒隊列不空
firstin(); //將就緒隊列的第一個進程投入運行
}
else //沒有運行完同時優先數不是最大,則將其變為就緒態插入到就緒隊列
if((ready!=NULL)&&(run->prio<ready->prio))
{
run->state='W';
insert1(run);
firstin(); //將就緒隊列的第一個進程投入運行
}
prt(alg); //輸出進程PCB信息
}
}
//主函數
void main()
{
char algo; //算法標記
//clrscr();
printf("輸入進程數:\n");
scanf("%d",&N); //輸入進程數
create1(algo); //優先數算法
priority(algo);
}
心得體會:因為有上一次實驗的經驗,所以做這一次實驗的困難不是很大,說到底還是練得少,加強練習必不可少

浙公網安備 33010602011771號