計算機作業系統——銀行家演算法
1.實驗目的:
銀行家演算法是由Dijkstra設計的最具有代表性的避免死鎖的演算法。本實驗通過編寫一個模擬動態資源分配的銀行家演算法程式,進一步深入理解死鎖、產生死鎖的必要條件、安全狀態等重要概念,並掌握避免死鎖的具體實施方法。
先對使用者提出的請求進行合法性檢查,即檢查請求的是不大於需要的,是否不大於可利用的。
若請求合法,則進行試分配。最後對試分配後的狀態呼叫安全性檢查演算法進行安全性檢查。
若安全,則分配,否則,不分配,恢復原來狀態,拒絕申請。
4.主要資料結構 § 可利用資源向量 int Available[m] m為資源種類 § 最大需求矩陣 int Max[n][m] n為程序的數量 §1. 銀行家演算法bank()函式
Requesti:程序Pi的請求向量。 0<=j<=m-1
(1)若Requesti[j] ≤Need[i,j],轉向(2),否則出錯。(2)若 Requesti[j] ≤Available[j],轉向(3),否則等待。
(3)系統試探著把資源分配給程序Pi,修改下面內容:Available[j]= Available[j] – Requesti[j];
Allocation[i,j]= Allocation[i,j]+ Requesti[j];
Need[i,j]= Need[i,j]–Requesti[j];
(4)試分配後,執行安全性演算法,檢查此次分配後系統是否處於安全狀態。若安全,才正式分配;否則,此次試探性分配作廢,程序Pi等待。2. 安全性演算法safe()函式
(1)初始化:設定兩個向量Work(1×m)和Finish(1×n)
Work– 系統可提供給程序繼續執行所需各類資源數,初態賦值AvailableFinish– 系統是否有足夠資源分配給程序,初值false.
(2)從程序集合中滿足下面條件程序:
Finish[i]= false; Need[i,j]≤Work[j];
若找到,執行(3),否則,執行(4)。
(3)程序Pi獲得資源,可順利執行,完成釋放所分配的資源。
Work[j]= Work[j]+Allocation[i,j]; Finish[i] = true; go to (2).
(4)若所有程序Finish[i]= true,表示系統處於安全狀態,否則處於不安全狀態。
6.程式結構程式共有以下五個部分:
§(1).初始化chushihua():輸入程序數量、資源種類、資源可利用量、程序資源已分配量、程序最大需求量 §(2).當前安全性檢查safe():用於判斷當前狀態安全。 §(3).銀行家演算法bank():進行銀行家演算法模擬實現的模組 §(4).顯示當前狀態show():顯示當前資源分配詳細情況 (5).主程式main():逐個呼叫初始化、顯示狀態、安全性檢查、銀行家演算法函式,使程式有序的進行。程式:
#include<iostream>
#include<cstring>
#define False 0
#define True 1
using namespace std;
/********
主要資料結構
********/
int N=50;//程序的最大數
int M=100;//資源的最大數
char NAME[100]={0};//資源的名稱
int Avaliable[100]={0};//可用資源矩陣
int Max[50][100]={0};//最大需求矩陣
intAllocation[50][100]={0};//系統已分配矩陣
int Need[50][100]={0};//還需要資源矩陣
int Request[100]={0};//請求資源向量
int Security[50]={0};//存放安全序列
int Work[100]={0};//存放系統可提供資源
int Finish[50]={0};
/********
初始化資料:輸入程序數量、資源種類、
各種資源可利用數量、
各程序的資源已分配數量、
各程序對資源最大需求量等。
********/
void chushihua()
{
/* n為程序個數,即矩陣行數,m為資源個數,即矩陣列數。*/
int i,j,n,m;
int number,flag;
char name;//輸入資源名稱
cout<<"系統可用資源個數為:";
cin>>m;
M=m;
for(i=0;i<m;i++)
{
cout<<"資源"<<i<<"的名稱:";
cin>>name;
NAME[i]=name;
cout<<"資源"<<name<<"的初始個數為:";
cin>>number;
Avaliable[i]=number;
}
cout<<endl;
cout<<"請輸入程序的數量:";
cin>>n;
N=n;
cout<<"請輸入各程序的最大需求矩陣的值("<<n<<"*"<<m<<"矩陣)[Max]:"<<endl;
for(i=0;i<n;i++)
for(j=0;j<m;j++)
cin>>Max[i][j];
int temp[100]={0};
do{
flag=0;
cout<<"請輸入各程序已經分配的資源量("<<n<<"*"<<m<<"矩陣)[Allocation]:"<<endl;
for(i=0;i<n;i++)
for(j=0;j<m;j++){
cin>>Allocation[i][j];
if(Allocation[i][j]>Max[i][j]) flag=1;
}
if(flag==1)
cout<<"申請的資源大於最大需求量,請重新輸入!";
cout<<endl;
}while(flag);
for(i=0;i<n;i++)
for(j=0;j<m;j++){
Need[i][j]=Max[i][j]-Allocation[i][j];
temp[j]+=Allocation[i][j];//每種資源已分配的總量
}
for(j=0;j<m;j++)
Avaliable[j]=Avaliable[j]-temp[j];
}
/********
顯示資源分配矩陣
********/
void showdata()
{
int i,j;
cout<<endl;
cout<<"*************************************************************"<<endl;
cout<<"系統目前可用的資源[Avaliable]:"<<endl;
for(i=0;i<M;i++)
cout<<NAME[i]<<" ";
cout<<endl;
for (j=0;j<M;j++)
cout<<Avaliable[j]<<"";//輸出分配資源
cout<<endl;
cout<<"系統當前的資源分配情況如下:"<<endl;
cout<<" Max Allocation Need"<<endl;
cout<<"程序名 ";
for(j=0;j<3;j++){
for(i=0;i<M;i++)
cout<<NAME[i]<<" ";
cout<<" ";
}
cout<<endl;
for(i=0;i<N;i++){
cout<<" P"<<i<<" ";
for(j=0;j<M;j++)
cout<<Max[i][j]<<" ";
cout<<" ";
for(j=0;j<M;j++)
cout<<Allocation[i][j]<<" ";
cout<<" ";
for(j=0;j<M;j++)
cout<<Need[i][j]<<" ";
cout<<endl;
}
}
/********
安全性演算法
********/
int safe()
{
int i,j,k=0,p,all;
//重新初始化Finish
for (j=0;j<N;j++)
Finish[j]=False;
for (j=0;j<M;j++)
Work[j]=Avaliable[j];
//找安全序列
for(i=0;i<N;i++){
all=0;//藉助all來判斷Need中某一行的每一列是否都小於等於對應的Work的每一列
for(j=0;j<M;j++){
if (Finish[i]==False&&Need[i][j]<=Work[j]){
all++;
if(all==M){
for(p=0;p<M;p++)
Work[p]=Work[p]+Allocation[i][p];//變分配數
Finish[i]=True;
Security[k]=i;
k++;//安全序列指標後移一位
i=-1; //迴圈結束後執行i++,使得i=0,保證每次查詢安全序列都從第一個程序開始找。
}
}
}
}
for(i=0;i<N;i++){
if(Finish[i]==False){
cout<<"系統不安全"<<endl;//不成功系統不安全
return -1;
}
}
cout<<"系統是安全的!"<<endl;//如果安全,輸出成功
cout<<"存在一個安全序列:";
for(i=0;i<N;i++){//輸出執行程序陣列
cout<<"P"<<Security[i];
if(i<N-1) cout<<"->";
}
cout<<endl;
return 0;
}
/********
利用銀行家演算法對申請資源對進行試分配
********/
void bank()
{
char ch;
int i,j,k;
int allow=1;
ch='y';
cout<<"請輸入請求分配資源的程序號(0-"<<N-1<<"):";
cin>>i;//輸入須申請資源的程序號
cout<<"請輸入程序P"<<i<<"要申請的資源個數:"<<endl;
for(j=0;j<M;j++)
{
cout<<NAME[j]<<":";
cin>>Request[j];//輸入需要申請的資源
}
for (j=0;j<M;j++){
if(Request[j]>Need[i][j])//判斷申請是否大於需求,若大於則出錯
{
cout<<"程序P"<<i<<"申請的資源大於它需要的資源";
cout<<" 分配不合理,不予分配!"<<endl;
ch='m';
break;
}
else {
if(Request[j]>Avaliable[j])//判斷申請是否大於當前可分配資源,若大於則出錯
{
cout<<"程序"<<i<<"申請的資源大於系統現在可利用的資源";
cout<<endl;
cout<<" 系統尚無足夠資源,不予分配!"<<endl;
ch='m';
break;
}
}
}
if(ch=='y') {
//根據程序需求量變換資源
for (j=0;j<M;j++) {
Avaliable[j]=Avaliable[j]-Request[j];
Allocation[i][j]=Allocation[i][j]+Request[j];
Need[i][j]=Need[i][j]-Request[j];
}
showdata();//根據程序需求量顯示變換後的資源
safe();//根據程序需求量進行銀行家演算法判斷
//如果不安全拒絕分配
for(k=0;k<N;k++)
{
if(Finish[k]==False) {allow=0; break;}
}
if (allow ==0)
{
for (j=0;j<M;j++) {
Avaliable[j]=Avaliable[j]+Request[j];
Allocation[i][j]=Allocation[i][j]-Request[j];
Need[i][j]=Need[i][j]+Request[j];}
cout<<"應拒絕程序P"<<i<<"的申請,此次嘗試分配作廢";
cout<<endl;
cout<<"還原資源分配矩陣";
showdata();
}
}
}
int main()//主函式
{
char choice;
cout<<"\t---------------------------------------------------"<<endl;
cout<<"\t|| ||"<<endl;
cout<<"\t|| 實驗二:銀行家演算法的實現 ||"<<endl;
cout<<"\t|| ||"<<endl;
cout<<"\t|| ||"<<endl;
cout<<"\t|| 在此輸入個人姓名:****** ||"<<endl;
cout<<"\t|| ||"<<endl;
cout<<"\t---------------------------------------------------"<<endl;
chushihua();//初始化資料
showdata();//顯示各種資源
safe();//用銀行家演算法判定系統是否安全
while(1){
cout<<endl;
cout<<endl;
cout<<"\t-------------------銀行家演算法演示------------------"<<endl;
cout<<"是否請求分配嗎?是請按y/Y,否請按其它鍵"<<endl;
cin>>choice;
if(choice=='y'||choice=='Y')
bank();
else break;
}
}