銀行家算法是操作系統課程里面為數不多的幾個算法之一,理解銀行家算法對理解進程的死鎖有很大的幫助。而銀行家算法本身並沒有太復雜的計算,只是在理解上有一個問題稍微難一點。
算法在執行過程中要求
1:每次在“未執行完”進程中找到一個可以滿足要求的進程來執行
2:如果當前狀態下所有進程都能夠執行完,才表示該狀態是安全的。
上面的第二點比較容易被忽視。下面是算法源碼,源碼中注釋比較多,在這里就不啰嗦了。
#include
"
StdAfx.h
"

#include
"
Afx.h
"

#define
MAX_PROCESSES 10
//
最大進程數目

//
查找一個可執行完進程,並返回進程編號,返回 -1 表示沒有進程可以執行
//
nPn ---- 進程數目
//
pA ---- 進程已申請資源數
//
pM ---- 進程請求的最大資源數
//
nL ---- 當前剩余的資源數目
//
finished ---- 已經執行完成的進程
static
int
S_PreExcute(
int
nPn,
const
int
*
pA,
const
int
*
pM,
int
nL,
const
int
*
finished)

...
{
for (int i=0; i<nPn; i++)

...{
if (!finished[i] && // 第一個條件:進程沒有執行完
(pM[i]-pA[i]) <= nL) // 第二個條件:剩余資源可以滿足該進程的執行
return i;
}
return -1;
}

//
判斷當前的狀態是否安全,同時給出安全序列
//
返回值:返回當前能夠執行完的進程數目。
//
nPn ---- 進程數目
//
pA ---- 進程已申請資源數
//
pM ---- 進程請求的最大資源數
//
nT ---- 系統中所有資源數
//
safety_seq ---- 進程執行的安全序列
int
S_SafeTest(
int
nPn,
const
int
*
pA,
const
int
*
pM,
int
nT,
int
*
safety_seq)

...
{
int nFN = 0; // 已執行完的進程數量
int *finished = new int[nPn]; // 進程能執行完標志

int nL = nT; // 系統剩余資源數

for (int i=0; i<nPn; i++)

...{
finished[i] = FALSE; // 初始化進程"能執行完"標志
nL -= pA[i]; // 初始化系統剩余資源數
}


while (nFN < nPn)

...{
// 找到一個可執行完進程
int nPid = S_PreExcute(nPn, pA, pM, nL, finished);
if (nPid < 0) // 查找失敗
break;
else // 查找成果

...{
nL += pA[nPid]; // 修改剩余資源數
safety_seq[nFN++] = nPid; // 添加到安全序列
finished[nPid] = TRUE; // 修改進程執行完標志
}
}

delete []finished;
return nFN;
}


void
Test_BanksAlgorithm_single()

...
{
int T = 10; // 系統擁有的資源數
#define PN 3 // 系統中進程數

int A[PN] = ...{2, 3, 3}; // 進程已申請資源數

int M[PN] = ...{4, 8, 6}; // 進程最大需求資源數
int SQ[PN]; // 安全序列

int fn = S_SafeTest(PN, A, M, T, SQ);
if (fn == PN)

...{
printf("Status Safety! Safety Sequence: ");
for (int i=0; i<fn; i++)
printf("%d ", SQ[i]);
printf(" ");
}
else
printf("Status Unsafety! ");
}
