1. 程式人生 > >3】預防程序死鎖的銀行家演算法

3】預防程序死鎖的銀行家演算法

// 作業系統_實驗三(銀行家演算法).cpp : 定義控制檯應用程式的入口點。
//

#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;

#define MaxNumber 20

static int n;
static int m;
static int Available[MaxNumber];
static int Max[MaxNumber][MaxNumber];
static int Allocation[MaxNumber][MaxNumber];
static int Need[MaxNumber][MaxNumber];
static int Request[MaxNumber];
static int SafeOrder[MaxNumber]; 
static bool Finish[MaxNumber];

static bool isDisplayAvaliable = true;
static char sourceName[] = {'A','B','C','D','E','F','G','H','I','J','K'};	  //資源名稱

void input();
bool isSystemSafe();
void bankerAlgorithm();
void display();

int main()
{
	input();
	bankerAlgorithm();
	system("pause");
	return 0;
}


void input()
{
	ifstream inData;
	inData.open("data.txt");
	//讀取資料
	inData>>n;
	inData>>m;

	for (int i=0;i<m;i++)
	{
		inData>>Available[i];
	}

	for (int i=0;i<n;i++)
	{
		for (int j=0;j<m;j++)
		{
			inData>>Allocation[i][j];
		}
	}

	for (int i=0;i<n;i++)
	{
		for (int j=0;j<m;j++)
		{
			inData>>Need[i][j];
		}
	}

	for (int i=0;i<n;i++)
	{
		for (int j=0;j<m;j++)
		{
			Max[i][j] = Need[i][j] + Allocation[i][j];
		}
	}
	cout<<"*****************************程式開始*******************************"<<endl;
	display();
	
}


bool isSystemSafe()
{
	int work[MaxNumber];
	for (int i=0;i<m;i++)   //m是資源個數A,B,C
	{
		work[i] = Available[i];
	}
	for (int i=0;i<n;i++)    //n是程序個數
	{
		Finish[i] = false;
		SafeOrder[i] = -1;  //初始化安全序列
	}

	int FinishNumebr = 0;
	int isSafe;
	int i =0,j;
	while(i<n)
	{
		isSafe = 0;
		for(j = 0;j<m;j++)
		{
			if (Finish[i]==false && Need[i][j]<=work[j])
			{
				isSafe++;
			}
			else
				break;
		}

		if (isSafe == m)  //當且僅當程序對應的所有資源的數量都滿足的時候才成立
		{
			Finish[i] = true;
			SafeOrder[FinishNumebr] = i;
			FinishNumebr++;
			for (j = 0;j<m;j++)
			{
				work[j] += Allocation[i][j];
			}
			i=0;  //找到滿足條件的程序後,從頭開始再進行尋找
		}
		else
			i++;

		if (FinishNumebr==n)
		{
			cout<<"**********************************Safe!******************************"<<endl;	
			cout<<"對應的安全序列為:"<<endl;
			cout<<"P"<<SafeOrder[0];
			for (int i=1;i<n;i++)
			{
				cout<<"-->"<<"P"<<SafeOrder[i] ;
			}
			cout<<endl;
			return true;
		}
	}

	cout<<"******************************unSafe!******************************"<<endl;	
	return false;
}

void bankerAlgorithm()
{
	int chooseProcess;
	char isContinue;

	while(true)
	{
		//設定兩個布林變數:判別請求向量是等待還是系統已經不再分配新的資源
		bool isRequestNeedOK = true;
		bool isRequestAvailableOK = true;

		cout<<"請輸入要申請資源的程序號(注意:第一個程序為0號,第二個程序為1號,以此類推!)"<<endl<<"chooseProcess=";
		cin>>chooseProcess;
		cout<<"請輸入程序所請求的各類資源的數量:(A B C)"<<endl;
		for (int i=0;i<m;i++)
		{
			cin>>Request[i];
		}
		//輸入錯誤判斷
		for (int i=0;i<m;i++)
		{
			if (Request[i]>Need[chooseProcess][i])
			{
				cout<<"**************************當前執行結果*****************************"<<endl;
				cout<<"您輸入的請求程序所對應的資源數量超過最大需求量,請重新輸入!"<<endl;
				// cout<<"****************************************************************"<<endl;
				isRequestNeedOK = false;
				continue;
			}
			if (Request[i]>Available[i])
			{
				cout<<"**************************當前執行結果*****************************"<<endl;
				cout<<"您輸入的請求程序的資源數量超過系統所供給的最大資源數量pi必須等待,請重新輸入!"<<endl;
				// cout<<"****************************************************************"<<endl;
				isRequestAvailableOK = false;
				continue;
			}
		}

		for (int j = 0;j<m;j++)
		{
			Available[j] -=Request[j];
			Allocation[chooseProcess][j] += Request[j];
			Need[chooseProcess][j] -= Request[j];
		}
		cout<<"**********************************************************************"<<endl;
		  

		if (!isSystemSafe())   //如何不滿足系統安全性演算法,將本次試探作廢,恢復到原來的值
		{
			for (int j = 0;j<m;j++)
			{
				Available[j] +=Request[j];
				Allocation[chooseProcess][j] -= Request[j];
				Need[chooseProcess][j] += Request[j];
			}
			//當請求向量Request滿足和Need、Available的關係時,證明系統已不能再分配資源
			if (isRequestAvailableOK&&isRequestNeedOK)
			{
				cout<<"**************************當前執行結果*****************************"<<endl;
				cout<<"當前可利用資源已經不能滿足任何程序的需求,故系統進入不安全狀態,系統不分配資源!"<<endl;
				cout<<"****************************************************************"<<endl;
			}
			
		}

		cout<<"嘗試根據p(i)發出的請求向量後的資源情況:"<<endl;
		display(); 

		cout<<"*******************************************************************"<<endl;
		cout<<"是否繼續輸入請求變數request進行測試,是(Y),否(N)"<<endl;
		cout<<"isContinue = ";
		cin>>isContinue;
		if (isContinue=='Y'||isContinue=='y')
		{
			//input();//實現多次請求(保留上一次請求的狀態)
			continue;
		}
		else if (isContinue=='N'||isContinue=='n')
		{
			cout<<"******************************程式結束*****************************"<<endl;
			break;
		}

	}
}


void display()
{	
	char processName[] = {'1','2','3','4','5','6'};

	cout<<"----------------------------------------------------------------------"<<endl;
	cout<<"當前程序個數為 n = "<<n<<endl;
	cout<<"當前資源個數為 m = "<<m<<endl;
	cout<<"系統可利用資源數情況如下:"<<endl;
	for (int i=0;i<m;i++)
	{
		cout<<setw(5)<<sourceName[i]<<" ";
	}
	cout<<endl;
	cout<<setw(5)<<Available[0]<<" ";
	cout<<setw(5)<<Available[1]<<" ";
	cout<<setw(5)<<Available[2]<<" "<<endl;

	cout<<"------------------------------------------------------------------------"<<endl;

	cout<<"processName";
	cout<<setw(10)<<"Max[][]"<<" ";
	cout<<setw(15)<<"Allocation[][]"<<" ";
	cout<<setw(10)<<"Need[][]"<<" ";
	if (isDisplayAvaliable)
	{
		cout<<setw(15)<<"available[][]";
	}
	cout<<endl;
	cout<<setw(15);
	for (int i=0;i<m;i++)
	{
		cout<<sourceName[i]<<setw(3);
	}

	cout<<setw(5);
	for (int i=0;i<m;i++)
	{
		cout<<sourceName[i]<<setw(3);
	}

	cout<<setw(10);
	for (int i=0;i<m;i++)
	{
		cout<<sourceName[i]<<setw(3);
	}

	if (isDisplayAvaliable)
	{
		cout<<setw(5);
		for (int i=0;i<m;i++)
		{
			cout<<sourceName[i]<<setw(3);
		}
	}
	cout<<endl;


	//設定矩陣輸出形式
	bool OnlyOneLineAvaliable = true;  //Avaliable陣列只輸出第一行
	for (int i=0;i<n;i++)
	{
		cout<<setw(5)<<"P"<<processName[i];
		cout<<setw(10);
		for (int j = 0;j<m;j++)
		{
			cout<<Max[i][j]<<setw(3);
		}

		cout<<setw(5);
		for (int j = 0;j<m;j++)
		{
			cout<<Allocation[i][j]<<setw(3);
		}

		cout<<setw(10);
		for (int j = 0;j<m;j++)
		{
			cout<<Need[i][j]<<setw(3);
		}

		if (isDisplayAvaliable&&OnlyOneLineAvaliable)
		{
			cout<<setw(5);
			for (int i=0;i<m;i++)
			{
				cout<<Available[i]<<setw(3);
			}
			OnlyOneLineAvaliable = false;
		}
		cout<<endl;
	}

}
注:程式碼中的引用【#include "stdafx.h"】不是自己編寫的程式哈。我這裡的編譯環境是VS2010,建立專案的時候選擇的是【自動生成標頭檔案】這樣做生成的程式.cpp會自動引用