使用動態優先權的程序排程演算法模擬
阿新 • • 發佈:2020-12-22
技術標籤:os
實驗五 使用動態優先權的程序排程演算法模擬
1、實驗目的
通過動態優先權演算法的模擬加深對程序概念程序排程過程的理解。
2、實驗內容
(1)用C語言來實現對N個程序採用動態優先權優先演算法的程序排程。
(2)每個用來標識程序的程序控制塊PCB用結構來描述,包括以下欄位:
•••• 程序標識數 ID。
•••• 程序優先數 PRIORITY,並規定優先數越大的程序,其優先權越高。
•••• 程序已佔用的CPU時間CPUTIME。
•••• 程序還需佔用的CPU時間ALLTIME。當程序執行完畢時,ALLTIME變為0。•••• 程序的阻塞時間STARTBLOCK,表示當程序再執行STARTBLOCK個時間片後,將進入阻塞狀態。
•••• 程序狀態START。
•••• 佇列指標NEXT,用來將PCB排成佇列。
(3)優先數改變的原則:
•••程序在就緒佇列中呆一個時間片,優先數加1。
•••程序每執行一個時間片,優先數減3。
(4)假設在排程前,系統中有5個程序,它們的初始狀態如下:
(3) 為了清楚的觀察各程序的排程過程,程式應將每個時間片內的情況顯示出來,參照的具體格式如下:
RUNNING PROG:i
READY-QUEUE:-〉id1-〉id2
BLOCK-QUEUE:-〉id3-〉id4
#include <iostream> #include <vector> using namespace std; //定義程序控制塊 struct PCB{ int Id; int Priority; //優先權 int CPU_time; //已佔用的cpu時間片 int All_time; //還需要的時間 int Start_block; //執行多少個時間片之後開始進入Block_time int Block_time; //阻塞的時間 int State; // 狀態 0為就緒 1為阻塞 2為完成 }; //給程序控制塊賦值 struct PCB p[5]= { {0,9,0,3,2,3,0}, {1,38,0,3,-1,0,0}, {2,30,0,6,-1,0,0}, {3,29,0,3,-1,0,0}, {4,0,0,4,-1,0,0} }; //容器,當作佇列用 vector<PCB> ready_queue;//就緒佇列 vector<PCB> block_queue;//阻塞佇列 vector<PCB> finish_queue;//結束佇列 //輸出函式 void print(){ cout<<"running prog:"<<ready_queue[0].Id<<endl; cout<<"ready_queue:"; for(int i=0;i<ready_queue.size();i++){ cout<<"-> "<<ready_queue[i].Id; } cout<<endl; cout<<"block_queue:"; for(int i=0;i<block_queue.size();i++){ cout<<"-> "<<block_queue[i].Id; } cout<<endl; cout<<"id\t prio\t cpu_time\t all_time\t "; cout<<"start_block\t block_time\t state"<<endl; for(int i=0;i<5;i++){ if(!ready_queue.empty()){ for(int a=0;a<ready_queue.size();a++){ if(ready_queue[a].Id==i){ cout<<ready_queue[a].Id<<"\t"<< ready_queue[a].Priority<<"\t" <<"\t"<<ready_queue[a].CPU_time<<"\t"; cout<<"\t"<<ready_queue[a].All_time<<"\t"<<"\t"<<ready_queue[a].Start_block<<"\t"<<"\t"<<ready_queue[a].Block_time<<"\t"<<"\t"<<ready_queue[a].State<<endl; break; } } } if(!block_queue.empty()){ for(int b=0;b<block_queue.size();b++){ if(block_queue[b].Id==i){ cout<<block_queue[b].Id<<"\t"<< block_queue[b].Priority<<"\t" <<"\t"<<block_queue[b].CPU_time<<"\t"; cout<<"\t"<<block_queue[b].All_time<<"\t"<<"\t"<<block_queue[b].Start_block<<"\t"<<"\t"<<block_queue[b].Block_time<<"\t"<<"\t"<<block_queue[b].State<<endl; break; } } } if(!finish_queue.empty()){ for(int c=0;c<finish_queue.size();c++){ if(finish_queue[c].Id==i){ cout<<finish_queue[c].Id<<"\t"<< finish_queue[c].Priority<<"\t"<<"\t"<<finish_queue[c].CPU_time<<"\t"; cout<<"\t"<<finish_queue[c].All_time<<"\t"<<"\t"<<finish_queue[c].Start_block<<"\t"<<"\t"<<finish_queue[c].Block_time<<"\t"<<"\t"<<finish_queue[c].State<<endl; break; } } } } } //沒一個時鐘脈衝之後,就對就緒佇列的內容重新排序 void sortqueue(){ //ready_queue裡面還有程序控制塊嗎?有或者沒有 if( (ready_queue.empty())&&(block_queue.empty()) ) return; else{ for(int i=0;i<ready_queue.size()-1;i++){ for(int j=i+1;j<ready_queue.size();j++){ if(ready_queue[i].Priority < ready_queue[j].Priority){ swap(ready_queue[i],ready_queue[j]); //冒泡演算法,swap交換函式 } } } } } //執行函式,其實是執行的就是就緒佇列的第一個單元, //執行相當於對第一個元素的某些值進行加減。 void run(){ if(!ready_queue.empty()){ //就緒佇列沒空 ready_queue[0].Priority-=3; ready_queue[0].CPU_time++; ready_queue[0].All_time--; //除了執行程序以外的程序優先權加1 for(int i=1;i<ready_queue.size();i++) ready_queue[i].Priority+=1; //已阻塞的程序再等待Block_time個時間片後,將轉換成就緒狀態。 if(!block_queue.empty()){ for(int i=0;i<block_queue.size();i++){ block_queue[i].Block_time--; if(block_queue[i].Block_time==0){ block_queue[i].State=0;//就緒 ready_queue.push_back(block_queue[i]); block_queue.erase(block_queue.begin()+i); } } }/*至此,是一個時間片對於某些因素的改變,至於是否到了佇列變換的時候,下方再去判斷*/ //全部遍歷一遍,是否需要去阻塞 for(int i=0;i<ready_queue.size();i++){ if(ready_queue[i].Start_block>0){ ready_queue[i].Start_block--; //去阻塞 if(ready_queue[i].Start_block==0){ ready_queue[i].State=1;//狀態為1 阻塞 block_queue.push_back(ready_queue[i]); ready_queue.erase(ready_queue.begin()+i); } } } //沒有執行時間,調入到結束佇列 if(ready_queue[0].All_time<=0){ ready_queue[0].State=2;//狀態為2 結束 finish_queue.push_back(ready_queue[0]);// push_back最後一個向量後插入一個元素 ready_queue.erase(ready_queue.begin()+0);//刪除第0個元素,並將後面的前移一位 } } } int main(){ //將所有的pcb輸入到就緒佇列裡面,再去排序 for(int i=0;i<5;i++){ ready_queue.push_back(p[i]); } int num=1; for(;!ready_queue.empty();){ cout<<num++<<"--------------------實時狀態------------------------"<<endl; sortqueue(); run(); print(); cout<<endl<<endl; } cout<<"執行完成"<<endl<<"執行時序為"; for(int i=0;i<5;i++) { cout<<finish_queue[i].Id; } return 0; }