模擬按優先數排程演算法(C++)
(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) 為五個程序任意確定一組“優先數”和“要求執行時間”,啟動所設計的處理器排程程式,顯示或列印逐次被選中程序的程序名以及程序控制塊的動態變化過程。
具體程式碼
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <vector>
using namespace std;
/************************************************************************/
/* 優先服務排程演算法(PCB) */
/************************************************************************/
struct PCB{
// 程序名稱
char name[10];
// 執行時間
int runtime;
// 優先順序
int frist;
// 狀態, R為就緒,F為完成
char state;
};
// 構造優先函式
void pcb(struct PCB *p, int N)
{
int i;
printf("請輸入程序的名字、優先順序、執行時間(例如:1 2 1)\n");
printf("\n");
for(i = 0; i < N; i++)
{
printf("請輸入第%d個程序的資訊:\n",i+1);
scanf("%s %d %d", p[i].name, &p[i].frist, &p[i].runtime);
//程序初始狀態均為就緒
p[i].state = 'R';
}
}
//確定最大優先順序程序子程式
int max_frist_process(struct PCB *p, int N)
{
//max為最大優先數,初始化為-10
int max = -10;
int i, key;
for(i = 0; i < N; i++)
{
//r表示正在執行
if(p[i].state == 'r')
return -1;
else
{
//從就緒程序中選取優先數最大的程序
if(max < p[i].frist && p[i].state == 'R')
{
//max存放每次迴圈中的最大優先數
max = p[i].frist;
key = i;
}
}
}
//具有最大優先數的程序若已執行完畢
if(p[key].state == 'F')
return -1;
else
return key;
}
void print(struct PCB *p, int N)
{
int i;
printf("\n程序名 優先順序 執行時間 當前狀態\n");
printf("*****************************************\n");
//依次顯示每個程序的名、優先數、要求執行時間和狀態
for(i = 0; i < N; i++)
{
printf(" %s\t %d\t %d\t %c\t\n", p[i].name, p[i].frist, p[i].runtime, p[i].state);
}
}
void run(struct PCB *p, int N)
{
int i, j;
// 執行次數
int t = 0;
for(j = 0; j < N; j++)
{
//執行次數即為各個程序執行時間之和
t += p[j].runtime;
}
printf("\n程序沒執行前,當前的狀態是:\n");
print(p, N);
vector<string> vec_out;
for(j = 0; j < t; j++)
{
//具有最大優先數的程序沒有執行完,讓其執行
while(max_frist_process(p, N) != -1)
{
//將其狀態置為r,表示其正在執行
p[max_frist_process(p, N)].state = 'r';
}
for(i = 0; i < N; i++)
{
if(p[i].state == 'r')
{
//將當前執行程序的優先數減1
p[i].frist -= 1;
//要求執行時間減1
p[i].runtime--;
//顯示每次執行後各PCB的情況
print(p, N);
printf("Process: %s, running @ time %d, priority %d, run_time %d\n",
p[i].name, j, p[i].frist, p[i].runtime);
string s = p[i].name;
vec_out.push_back(s);
{
if(p[i].runtime == 0)
//執行完則將該程序狀態置為結束
p[i].state = 'F';
else
//未執行完將其狀態置為就緒
p[i].state = 'R';
}
}
}
}
printf("執行順序:\n");
printf("%s", vec_out[0].c_str());
for(int i = 1; i < vec_out.size(); i++)
{
printf("-->%s", vec_out[i].c_str());
}
}
void PCB_MAIN()
{
int N;
printf("請輸入程序的數量:\n");
scanf("%d",&N);
struct PCB *p = new struct PCB[N];
// 初始化
pcb(p, N);
// 程序排程模擬
run(p, N);
delete[] p;
}
int main()
{
PCB_MAIN();
return 0;
}
輸出例項