作業系統實驗------處理機排程
實驗一 處理機排程實驗
一、 實驗目的:
用高階語言編寫和除錯一個程序排程程式,以加深對程序的概念及程序排程演算法的理解。
二、 實驗要求:
用C++語言實驗對N個程序採用非搶佔式的動態優先權優先演算法的程序排程
三、 實驗內容:
(1) 設計一個有N個程序併發的程序排程程式。程序排程演算法:採用最高優先數優先的排程演算法(即把處理機分配給優先數最高的程序)演算法。
(2) 每個程序有一個程序控制塊(PCB)表示。PCB用結構來描述,包括以下欄位:
l 程序標識ID、
l 優先數,為初始設定的模擬條件
l 到達時間,為初始設定的模擬條件
l 需要執行時間,為初始設定的模擬條件
l 已用CPU時間,為初始設定的模擬條件
l 程序阻塞時間startblock(表示程序在執行startblock個時間片後,程序將進入阻塞狀態),為初始設定的模擬條件
l 程序被阻塞的時間blocktime(表示程序等待blocktime個時間片後,將轉換成就緒狀態),為初始設定的模擬條件,模擬執行I/O操作需要的時間
l 程序狀態state,就緒W(Wait)、執行R(Run)、或完成F(Finish)三種狀態
l 佇列指標next等等。
(3) 優先數改變的規則
程序在就緒佇列中呆一個時間片,優先數增加1;
程序每執行一個時間片,優先數減3;
(4) 執行過程描述
首先按照初始化輸入,按照各程序優先順序高低排列就緒佇列中程序順序,優先順序最高的程序最先獲得CPU控制權執行。如果執行一個時間片後,程序的已佔用CPU時間已達到所需要的執行時間,則撤消該程序,如果執行一個時間片後進程的已佔用CPU時間還未達所需要的執行時間,此時應將程序的優先數減3(即降低一級),如果到了程序需被阻塞的時間點,阻塞程序,然後把它插入阻塞佇列,等待經過blocktime後,再喚醒程序,把它按照優先順序高低,插入就緒佇列相應位置等待CPU。
每進行一次排程程式都列印一次執行程序、就緒佇列、以及各個程序的PCB,以便進行檢查。
重複以上過程,直到所要程序都完成為止。
備註:程序的優先數及需要的執行時間可以事先人為地指定(也可以由隨機數產生)。
程序的到達時間為程序輸入的時間或順序。
參考資料:
部分資料結構說明:
struct pcb { /* 定義程序控制塊PCB */
char name[10];
char state;
int super;
int ntime;
int rtime;
。。。。。。。。。。。。。。。
struct pcb* link;
};
程式碼:
#include<iostream> #include<string> #include<cstdio> #include<vector> #include<stdio.h> #include<queue> using namespace std; typedef struct PCB{ int Id;//程序標識 int Number;//優先數 int ArrivedTime;//到達時間 int NeedTime;//需要執行時間 int UserTime;//已用CPU時間 int BlockTime;//程序被阻塞的時間 int StartblockTime;//程序阻塞時間 char stat[6];//程序狀態 int True;//標誌是否執行結束 int TrueZuse; int InZuSeTime; }; //定義優先佇列排序 bool operator < (PCB n1,PCB n2) { return n1.Number<n2.Number;//最大優先 } PCB pcb[50]; priority_queue<PCB> q;//就緒佇列 priority_queue<PCB> Q;//阻塞佇列 int AllTime=0; int INFI=3; //將程序插進就緒佇列 void insertq(){ for (int i=0; i<INFI; i++){ //判斷是否已經執行結束 if (pcb[i].True==0) { q.push(pcb[i]); } } } //判斷是否執行結束 int IsFinish(PCB pcb) { if(pcb.True==1) return 1; else return 0; } //列印程序資訊 void PutOut(PCB pcb) { printf("Id=%d\n",pcb.Id); printf("Number=%d\n",pcb.Number); printf("ArrivedTime=%d\n",pcb.ArrivedTime); printf("NeedTime=%d\n",pcb.NeedTime); printf("UserTime=%d\n",pcb.UserTime); printf("BlockTime=%d\n",pcb.BlockTime); printf("StartblockTime=%d\n",pcb.StartblockTime); printf("stat=%s\n",pcb.stat); printf("True=%d\n",pcb.True); printf("TrueZuse=%d\n",pcb.TrueZuse); printf("InZuSeTime=%d\n",pcb.InZuSeTime); printf("...........下一個程序詳情............\n"); } //初始化程序 void init() { pcb[0].Id=0; pcb[0].Number=8; pcb[0].ArrivedTime=0; pcb[0].NeedTime=3; pcb[0].UserTime=0; pcb[0].StartblockTime=1; pcb[0].BlockTime=1; pcb[0].stat[0]='w'; pcb[0].stat[1]='a'; pcb[0].stat[2]='i'; pcb[0].stat[3]='t'; pcb[0].True=0; pcb[0].TrueZuse=0; pcb[1].Id=1; pcb[1].Number=10; pcb[1].ArrivedTime=0; pcb[1].NeedTime=4; pcb[1].UserTime=0; pcb[1].StartblockTime=12; pcb[1].BlockTime=12; pcb[1].stat[0]='w'; pcb[1].stat[1]='a'; pcb[1].stat[2]='i'; pcb[1].stat[3]='t'; pcb[1].True=0; pcb[1].TrueZuse=0; pcb[2].Id=2; pcb[2].Number=5; pcb[2].ArrivedTime=0; pcb[2].NeedTime=2; pcb[2].UserTime=0; pcb[2].StartblockTime=122; pcb[2].BlockTime=1222; pcb[2].stat[0]='w'; pcb[2].stat[1]='a'; pcb[2].stat[2]='i'; pcb[2].stat[3]='t'; pcb[2].True=0; pcb[2].TrueZuse=0; } int main() { init(); insertq(); int gg =0; AllTime=1; while(gg<7){ //if (q.size()<=0)continue; PCB pcbb; int id=0; pcbb = q.top(); id = pcbb.Id; //判斷程序阻塞時間是否到了 for (int i=0; i<INFI; i++) { if (pcb[i].UserTime == pcb[i].StartblockTime && pcb[i].TrueZuse!=1) { //阻塞時間到,插進阻塞佇列 Q.push(pcb[i]); pcb[i].TrueZuse=1;//標記阻塞 pcb[i].InZuSeTime=AllTime; } } if (!IsFinish(pcb[id])) pcb[id].UserTime++; //判斷是否執行結束 if (pcb[id].UserTime>=pcb[id].NeedTime) { pcb[id].True=1; pcb[id].stat[0]='F'; pcb[id].stat[1]='i'; pcb[id].stat[2]='n'; pcb[id].stat[3]='i'; pcb[id].stat[4]='s'; pcb[id].stat[5]='h'; } //減優先數 pcb[id].Number=pcb[id].Number-3; //就緒佇列中每個加1 for (int i=0; i<INFI; i++) { //判斷是否在就緒中列中 if (pcb[i].TrueZuse==0 && pcb[i].Id!=id&&!IsFinish(pcb[i])) { //優先數加一 pcb[i].Number++; } } if (!Q.empty()) { //判斷阻塞時間是否結束 for (int i=0; i<INFI; i++) { //判斷是否在阻塞佇列中 if (pcb[i].TrueZuse==1) { //判斷阻塞時間是否結束 if (pcb[i].BlockTime == AllTime - pcb[i].InZuSeTime) { pcb[i].TrueZuse=0; } } } } //列印所有程序資訊 for (int i=0; i<INFI; i++) { PutOut(pcb[i]); q.pop(); } insertq(); gg++; AllTime++; printf("...........第%d時間片............\n",gg); } }