1. 程式人生 > 其它 >使用動態優先權的程序排程演算法模擬

使用動態優先權的程序排程演算法模擬

技術標籤:os

實驗五 使用動態優先權的程序排程演算法模擬

1、實驗目的
通過動態優先權演算法的模擬加深對程序概念程序排程過程的理解。
2、實驗內容
(1)用C語言來實現對N個程序採用動態優先權優先演算法的程序排程。
(2)每個用來標識程序的程序控制塊PCB用結構來描述,包括以下欄位:
•••• 程序標識數 ID。
•••• 程序優先數 PRIORITY,並規定優先數越大的程序,其優先權越高。
•••• 程序已佔用的CPU時間CPUTIME。
•••• 程序還需佔用的CPU時間ALLTIME。當程序執行完畢時,ALLTIME變為0。•••• 程序的阻塞時間STARTBLOCK,表示當程序再執行STARTBLOCK個時間片後,將進入阻塞狀態。

•••• 程序被阻塞的時間BLOCKTIME,表示已足賽的程序再等待BLOCKTIME個時間片後,將轉換成就緒狀態。
•••• 程序狀態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;
}