操作系統實驗-設計一個按優先數調度算法實現處理器調度的程序

實驗二
一、實驗題目
設計一個按優先數調度算法實現處理器調度的程序
二、實驗內容
(1) 假定系統有五個進程,每一個進程用一個進程控制塊PCB來代表,進程控制塊的格式爲:
|進程名|
|指針|
|要求運行時間|
|優先數|
|狀態|
其中,進程名——作爲進程的標識,假設五個進程的進程名分別爲P1,P2,P3,P4,P5。
指針——按優先數的大小把五個進程連成隊列,用指針指出下一個進程的進程控制塊的首地址,最後一個進程中的指針爲“0”。
要求運行時間——假設進程需要運行的單位時間數。
優先數——賦予進程的優先數,調度時總是選取優先數大的進程先執行。
狀態——可假設有兩種狀態,“就緒”狀態和“結束”狀態。五個進程的初始狀態都爲“就緒”,用“R”表示,當一個進程運行結束後,它的狀態爲“結束”,用“E”表示。
(2) 在每次運行你所設計的處理器調度程序之前,爲每個進程任意確定它的“優先數”和“要求運行時間”。
(3) 爲了調度方便,把五個進程按給定的優先數從大到小連成隊列。用一單元指出隊首進程,用指針指出隊列的連接情況。例:
隊首標誌
在這裏插入圖片描述
(4) 處理器調度總是選隊首進程運行。採用動態改變優先數的辦法,進程每運行一次優先數就減“1”。由於本實驗是模擬處理器調度,所以,對被選中的進程並不實際的啓動運行,而是執行:
優先數-1
要求運行時間-1
來模擬進程的一次運行。
提醒注意的是:在實際的系統中,當一個進程被選中運行時,必須恢復進程的現場,讓它佔有處理器運行,直到出現等待事件或運行結束。在這裏省去了這些工作。
(5) 進程運行一次後,若要求運行時間0,則再將它加入隊列(按優先數大小插入,且置隊首標誌);若要求運行時間=0,則把它的狀態修改成“結束”(E),且退出隊列。
(6) 若“就緒”狀態的進程隊列不爲空,則重複上面(4)和(5)的步驟,直到所有進程都成爲“結束”狀態。
(7) 在所設計的程序中應有顯示或打印語句,能顯示或打印每次被選中進程的進程名以及運行一次後進程隊列的變化。
(8) 爲五個進程任意確定一組“優先數”和“要求運行時間”,啓動所設計的處理器調度程序,顯示或打印逐次被選中進程的進程名以及進程控制塊的動態變化過程。
三、實驗過程
1、實驗原理
(1) 假定系統有5個進程,每個進程用一個PCB來代表。PCB的格式爲:
進程名、指針、要求運行時間、優先數、狀態。
進程名——P1~P5。
指針——按優先數的大小把5個進程連成隊列,用指針指出下一個進程PCB的首地址。 要求運行時間——假設進程需要運行的單位時間數。
優先數——賦予進程的優先數,調度時總是選取優先數大的進程先執行。
狀態——假設兩種狀態,就緒,用R表示,和結束,用E表示。初始狀態都爲就緒狀態。
(2) 每次運行之前,爲每個進程任意確定它的“優先數”和“要求運行時間”。
(3) 處理器總是選隊首進程運行。採用動態改變優先數的辦法,進程每運行1次,優先數減1,要求運行時間減1。
(4) 進程運行一次後,若要求運行時間不等於0,則將它加入隊列,否則,將狀態改爲“結束”,退出隊列。
(5) 若就緒隊列爲空,結束,否則,重複(3)。
2、數據結構
在這裏插入圖片描述
進程控制塊PCB:proName:進程名;runTime:運行時間;priorityNum:優先級;status:狀態
優先隊列readyQueue:就緒隊列

3、算法設計
void tailCreate(PCB *L){
srand((unsigned int)time(0));
///以時間爲隨機數種子,保證每次隨機數不一樣
int priority = rand() % 5;///隨機優先數
PCB *s, *r = L;
for (int i = 0; i<5; i++)
{ ///隨機時間爲1到50
int number = rand() % 5;
while (number == 0)
///如果是0就一直隨機,直到出現不是0的爲止
number = rand() % 5;
///tail_insert用尾插法初始化
s = new PCB;
s->pid = i + 1;
s->priority = (i + priority) % 5 + 1;
s->time = number;
if (s->priority != 5 || r->next == NULL)
///如果r->next== NULL表示爲隊列只有一個頭結點,就直接插入
{ r->next = s;
r = s;}
if ((s->priority == 5) && (r->next != NULL))
///如果隊列不爲空,就將它放在頭結點後面
{
s->next = L->next;
L->next = s;
}
}
r->next = NULL;}
void run(PCB L)///運行
{
PCB c = L; PCB p = L;
for (L; L; L = L->next)
{
if (L->next == NULL)
break;
///由於存在存在頭結點,所以從L->next開始
L->next->priority = L->next->priority - 1;
L->next->time = L->next->time - 1;
if (L->next->time == 0){
///如果運行時間爲0,就將它移除隊列中 {
cout << “run over” <<"->PID->"<< L->next->pid << endl;
L->next->time = -1;
L->next = L->next->next;
///由於出現了L->next = L->next->next;這步,
///接着執行for循環的第三個表達式,便跳過了L->next->next這個結點,接着執行L->next->next->next這個結點
///所以需要判斷一下L->next->next這個結點
if (L->next != NULL&&L->next->time != 0)
{ L->next->priority = L->next->priority - 1;
L->next->time = L->next->time - 1;
}
///如果L->next->next->time的值等於0,便會將它移除隊列,接着執行L->next=L->next->next這步
///所以需要while循環來判斷
四、實驗結果
在這裏插入圖片描述
五、體會與收穫
通過本次實驗,我對優先數調度算法有了一定掌握。這道題慢悠悠地做,出現了很多錯誤,大多都是空指針產生的中斷,最後還是實現了。希望以後自己在寫代碼的時候再仔細再認真一下。
六、源代碼
#include
#include <time.h>
#include <stdlib.h>
using namespace std;
static int point = 0;
///用於計算進程是否運行完成
struct PCB{
int pid;
int priority;
int time;
PCB next;
};
void tailCreate(PCB L){
srand((unsigned int)time(0));
///以時間爲隨機數種子,保證每次隨機數不一樣
int priority = rand() % 5;///隨機優先數
PCB s, r = L;
for (int i = 0; i<5; i++)
{ ///隨機時間爲1到50
int number = rand() % 5;
while (number == 0)
///如果是0就一直隨機,直到出現不是0的爲止
number = rand() % 5;
///tail_insert用尾插法初始化
s = new PCB;
s->pid = i + 1;
s->priority = (i + priority) % 5 + 1;
s->time = number;
if (s->priority != 5 || r->next == NULL)
///如果r->next==NULL表示爲隊列只有一個頭結點,就直接插入
{
r->next = s;
r = s;
}
if ((s->priority == 5) && (r->next != NULL))
///如果隊列不爲空,就將它放在頭結點後面
{
s->next = L->next;
L->next = s;
}
}
r->next = NULL;}
void run(PCB L)///運行
{
PCB c = L; PCB p = L;
for (L; L; L = L->next)
{
if (L->next == NULL)
break;
///由於存在存在頭結點,所以從L->next開始
L->next->priority = L->next->priority - 1;
L->next->time = L->next->time - 1;
if (L->next->time == 0){
///如果運行時間爲0,就將它移除隊列中 {
cout << “run over” <<"->PID->"<< L->next->pid << endl;
L->next->time = -1;
L->next = L->next->next;
///由於出現了L->next = L->next->next;這步,
///接着執行for循環的第三個表達式,便跳過了L->next->next這個結點,接着執行L->next->next->next這個結點
///所以需要判斷一下L->next->next這個結點
if (L->next != NULL&&L->next->time != 0)
{
L->next->priority = L->next->priority - 1;
L->next->time = L->next->time - 1;
}
///如果L->next->next->time的值等於0,便會將它移除隊列,接着執行L->next=L->next->next這步
///所以需要while循環來判斷
while (L->next != NULL&&L->next->time == 0)
{
cout << “run over” <<"->PID->"<< L->next->pid << endl;
L->next->time = -1;
L->next = L->next->next;
point = point + 1;
if (L->next != NULL)
{
L->next->priority = L->next->priority - 1;
L->next->time = L->next->time - 1;
}
}
point = point + 1;
}
if (L->next != NULL&&L->next->priority == 0)
///如果優先數爲0就將它變成0放在隊首
{ //

PCB q = L->next;
L->next = L->next->next;
q->priority = 5;
q->next = c->next;
c->next = q;
///由於執行了L->next=L->next->next
///所以又會執行上面那步同樣地操作
if (L->next != NULL&&L->next->time != 0)
{
L->next->priority = L->next->priority - 1;
L->next->time = L->next->time - 1;
}
while (L->next != NULL&&L->next->time == 0)
{
cout << “run over” << “->PID->”<next->pid << endl;
L->next->time = -1;
L->next = L->next->next;
point = point + 1;
if (L->next != NULL)
{
L->next->priority = L->next->priority - 1;
L->next->time = L->next->time - 1;
}
}
}
}
L = p;
}
int main(){ PCB L, m; L = new PCB;
//初始化頭結點
L->next = NULL; tailCreate(L);
m = L;
L = L->next;
cout << “=" << endl;
cout << “Init” << endl;
cout << "
==” << endl;
for (L; L; L = L->next)
{ cout <<“PID :”<< L->pid << endl;
cout << “Time :”<time << endl;
cout << “Priority :”<priority << endl;
cout << "
" << endl;
cout << endl; }
cout << "============= " << endl;
cout << “Init successful!” << endl;
cout << “==============” << endl;
cout << endl;
cout << “run order!” << endl;
while (point != 5)
{
run(m);
}
system(“pause”);
return 0; }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章