銀行家算法是針對操作系統資源分配中可能導致的死鎖問題,主要是通過對資源請求滿足之後的狀態檢測,如果滿足請求之後系統狀態安全,則說明不會產生死鎖,可以滿足申請;如果滿足之後的狀態不安全,則有可能會形成死鎖,故而不能滿足請求。從而達到避免死鎖的發生。
死鎖檢測需要使用安全性算法,該算法只用於對當前狀態是否爲死鎖進行檢測,這裏用於在銀行家算法中對於滿足請求之後的系統狀態進行檢測。其中,死鎖的檢測方法還有RAG圖,該算法也可用於死鎖的檢測。
銀行家算法代碼:
bool bankerAlgorithm()
{
int pos;
int i = 0;
int flag = 0;
vector<int> request;
vector<vector<int> > ::iterator p;
request.resize(Available.size());
printMatrix(Allocation, Need, Available);
cout << "請輸入申請資源的進程號:";
while (cin >> pos)
{
if (pos >= 0 && pos <= Need.size())
{
break;
}
else
{
cout << "進程號輸入錯誤,請重新輸入:";
}
}
cout << "請輸入" << pos << "進程的各個資源申請個數:";
for (auto &i : request)
{
cin >> i;
}
if (matrixGreatJudgment(request, Need[pos]))
{
cout << "請求大於合法需求!" << endl;
return false;
}
else if (matrixGreatJudgment(request, Available))
{
cout << "系統當前可用資源數不滿足需求!" << endl;
return false;
}
/****** 試分配 ************/
vector<vector<int> >bankAll = Allocation;
vector<vector<int> >bankNeed = Need;
vector<int> bankAvailable = Available;
addMatrix(bankAll[pos], request);
for (i = 0; i < bankNeed[pos].size(); i++)
{
bankNeed[pos][i] -= request[i];
bankAvailable[i] -= request[i];
}
for (auto &k : bankNeed[pos])
{
if (k != 0)
{
flag = 1;
break;
}
}
if (flag == 0)//當前申請的資源滿足lpos進程的運行條件,運行結束,回收資源 ,進程撤銷
{
bankAvailable=addMatrix(bankAvailable, bankAll[pos]);//回收資源
bankAll.erase(bankAll.begin() + pos);//進程撤銷
bankNeed.erase(bankNeed.begin() + pos);//進程撤銷
}
//試分配結束
cout << "試分配後拷貝矩陣狀態:" << endl;
printMatrix(bankAll, bankNeed, bankAvailable);
if (securityAlgorithm(bankAll, bankNeed, bankAvailable))
{
cout << "該申請可以滿足!滿足之後的矩陣狀態爲:"<<endl;
Need = bankNeed;
Allocation = bankAll;
Available = bankAvailable;
printMatrix(Allocation, Need, Available);
return true;
}
else
{
cout << "滿足需求會使陷入不安全狀態,不能滿足需求!矩陣不發生改變" << endl;
printMatrix(Allocation, Need, Available);
return false;
}
}
在其實現過程中,由於我們要知道滿足請求之後的系統狀態,所以我們需要進行試分配,通過矩陣的拷貝,對拷貝來的矩陣副本進行分配,並檢測分配後的狀態。下面這段就是對矩陣的拷貝和拷貝後的預分配處理。
/****** 試分配 ************/
vector<vector<int> >bankAll = Allocation;
vector<vector<int> >bankNeed = Need;
vector<int> bankAvailable = Available;
addMatrix(bankAll[pos], request);
for (i = 0; i < bankNeed[pos].size(); i++)
{
bankNeed[pos][i] -= request[i];
bankAvailable[i] -= request[i];
}
其中有考慮到分配後進程所有資源均被滿足,進程執行完後撤銷,釋放所有已佔用資源,因此下面這段代碼實現了該部分功能。
for (auto &k : bankNeed[pos])
{
if (k != 0)
{
flag = 1;
break;
}
}
if (flag == 0)//當前申請的資源滿足lpos進程的運行條件,運行結束,回收資源 ,進程撤銷
{
bankAvailable=addMatrix(bankAvailable, bankAll[pos]);//回收資源
bankAll.erase(bankAll.begin() + pos);//進程撤銷
bankNeed.erase(bankNeed.begin() + pos);//進程撤銷
}
最後來看一下整個代碼吧!Banker's Algorithm Code