一、實驗目的
用高級語言完成一個進程調度程序,以加深對進程的概念及進程調度算法的理解。
二、實驗內容和要求
設計一個有 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,再按照優先級從高到低排序,選擇最高優先級進程調度,如果兩進程優先級相同,則按照先來先服務算法,先到達的先調度。
四、實驗總結
實驗從字面容易理解,但實踐過程中還是相當有難度,但經過老師的講解和同學的幫助,算是勉強完成,今后需多加努力。

