1. 程式人生 > >計算機作業系統——銀行家演算法

計算機作業系統——銀行家演算法

1.實驗目的:

銀行家演算法是由Dijkstra設計的最具有代表性的避免死鎖的演算法。本實驗通過編寫一個模擬動態資源分配的銀行家演算法程式,進一步深入理解死鎖、產生死鎖的必要條件、安全狀態等重要概念,並掌握避免死鎖的具體實施方法。

2.實驗內容:        (1)模擬一個銀行家演算法:   設定資料結構   設計安全性演算法 (2)初始化時讓系統擁有一定的資源; (3)用鍵盤輸入的方式申請資源; (4)如果預分配後,系統處於安全狀態,則修改系統的資源分配情況; (5)如果預分配後,系統處於不安全狀態,則提示不能滿足請求 3.演算法思路:

先對使用者提出的請求進行合法性檢查,即檢查請求的是不大於需要的,是否不大於可利用的。

若請求合法,則進行試分配。最後對試分配後的狀態呼叫安全性檢查演算法進行安全性檢查。

若安全,則分配,否則,不分配,恢復原來狀態,拒絕申請。

4.主要資料結構 § 可利用資源向量   int Available[m]   m為資源種類 § 最大需求矩陣       int Max[n][m]     n為程序的數量 §
分配矩陣               int Allocation[n][m] § 資源 矩陣       int need[i][j] = Max[i][j]- Allocation[i][j] § 申請資源數量       
int Request [m]   § 工作向量               int Work[m]   int Finish[n]  5.演算法描述

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– 系統可提供給程序繼續執行所需各類資源數,初態賦值Available

Finish– 系統是否有足夠資源分配給程序,初值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;

      }

}