银行家算法(单项资源)
文中给出了单项资源的银行家算法。本文给出的是多种资源的银行家算法。在本质上,单项资源的银行家算法和多种资源的银行家算法没有什么区别,只是书写起来有一点点不同(用C的语法,如果用C++的语法几乎可以写得一模一样)。有关银行家算法的问题大家可以看银行家算法(单项资源) 内容,在此不在赘述。此处只给出源码供大家参考。
不过里面有一个定义
//
定义RES_VECTOR向量,便于程序的理解
typedef int RES_VECTOR[MAX_RESOURCES];
typedef int RES_VECTOR[MAX_RESOURCES];
这个问题大家可以看typedef使用大全1(数组)
#include
"
StdAfx.h
"
#include " Afx.h "
#define MAX_PROCESSES 100 // 最大进程数目
#define MAX_RESOURCES 10 // 最多资源数目
// 定义RES_VECTOR向量,便于程序的理解
typedef int RES_VECTOR[MAX_RESOURCES];
// 该程序完成的是银行家算法的核心算法部分,即:判断当前的状态是否
// 是安全的。根据银行家算法,在一个进程提出资源请求时,系统为了避
// 免死锁要对该行为进行判断。如果该行为导致后续系统状态安全,则系
// 统自动满足该请求;否则,如果该行为导致后续系统状态不安全,显然
// 系统要禁止当前的请求,也就是要阻塞请求资源的进程。而该程序就是
// 能判断一个状态[预分配状态]是否是安全状态,判断安全状态的函数是
// M_SafeTest,其他的都是辅助函数,所以采用了static来修饰。
// writed by Houjian Tang
// 判断系统状态是否安全
int M_SafeTest( int nPn, int nRn,
const RES_VECTOR * pVA,
const RES_VECTOR * pVM,
RES_VECTOR vT,
int * safety_seq);
// 获得一个“能执行完”进程
static int M_PreExcute( int nPn,
int nRn,
const RES_VECTOR * pVA,
const RES_VECTOR * pVM,
const RES_VECTOR vL,
const int * finished);
// 向量比较
static int LessEqul( int nRn, const RES_VECTOR Va, const RES_VECTOR Vb);
// 计算向量之差
static void GetSub(RES_VECTOR v, int nRn, const RES_VECTOR va, const RES_VECTOR vb);
// 计算向量之和
static void GetAdd(RES_VECTOR v, int nRn, const RES_VECTOR va, const RES_VECTOR vb);
// 算法测试函数
void Test_BanksAlgorithm_multi();
// 比较两个向量的大小,如果pA<=pB小于等于,返回非0, 否则返回0值
static int LessEqul( int nRn, const RES_VECTOR Va, const RES_VECTOR Vb)
... {
int i;
for (i=0; i<nRn; i++)
...{
if (Va[i] > Vb[i])
return FALSE;
}
return TRUE;
}
// 计算向量减法,即v=va-vb
static void GetSub(RES_VECTOR v, int nRn, const RES_VECTOR va, const RES_VECTOR vb)
... {
int i;
for (i=0; i<nRn; i++)
v[i] = va[i] - vb[i];
}
// 计算向量加法,即v=va+vb
static void GetAdd(RES_VECTOR v, int nRn, const RES_VECTOR va, const RES_VECTOR vb)
... {
int i;
for (i=0; i<nRn; i++)
v[i] = va[i] + vb[i];
}
// 查找一个可执行完进程,并返回进程编号,返回 -1 表示没有进程可以执行
// nPn ---- 进程数目
// nRn ---- 资源数目
// pVA ---- 进程已申请资源数
// pVM ---- 进程请求的最大资源数
// vL ---- 当前剩余的资源数目
// finished ---- “能执行完”标志
static int M_PreExcute( int nPn,
int nRn,
const RES_VECTOR * pVA,
const RES_VECTOR * pVM,
const RES_VECTOR vL,
const int * finished)
... {
RES_VECTOR vQ; // 还需要的资源数
int i;
// 在每一个进程中查找一个可以运行完的进程
for (i=0; i<nPn; i++)
...{
GetSub(vQ, nRn, pVM[i], pVA[i]);
if (!finished[i] && // 第一个条件:进程没有执行完
LessEqul(nRn, vQ, vL)) // 第二个条件:剩余资源可以满足该进程的执行
return i;
}
return -1;
}
// 判断当前的状态是否安全,同时给出安全序列
// 返回值:返回当前能够执行完的进程数目。
// nPn ---- 进程数目
// pA ---- 进程已申请资源数
// pM ---- 进程请求的最大资源数
// nT ---- 系统中所有资源数
// safety_seq ---- 进程执行的安全序列
int M_SafeTest( int nPn, int nRn,
const RES_VECTOR * pVA,
const RES_VECTOR * pVM,
RES_VECTOR vT,
int * safety_seq)
... {
int nFN = 0; // 已执行完的进程数量
int *finished = new int[nPn]; // 进程能执行完标志
int i;
// 系统剩余资源数
RES_VECTOR vL;
for (i=0; i<nRn; i++)
vL[i] = vT[i];
// 初始化“能运行完”标志和系统剩余资源数
for (i=0; i<nPn; i++)
...{
finished[i] = FALSE; // 初始化进程"能执行完"标志
GetSub(vL, nRn, vL, pVA[i]); // 初始化系统剩余资源数
}
// 主循环,每次找一个进程,找不到则终止退出
while (nFN < nPn)
...{
// 找到一个“可执行完”进程
int nPid = M_PreExcute(nPn, nRn, pVA, pVM, vL, finished);
if (nPid >= 0) // 查找成功
...{
GetAdd(vL, nRn, vL, pVA[nPid]); // 修改剩余资源数
safety_seq[nFN++] = nPid; // 添加到安全序列
finished[nPid] = TRUE; // 修改进程执行完标志
}
else
...{
// 如果查找失败,则直接退出
break;
}
}
delete []finished;
return nFN;
}
// 算法测试函数
void Test_BanksAlgorithm_multi()
... {
RES_VECTOR T = ...{6, 3, 4, 2}; // 系统拥有的资源数
#define PN 5 // 系统中进程数
#define RN 4 // 系统中拥有的资源种类数
// 进程已申请资源数
RES_VECTOR VA[PN] = ...{
...{3, 0, 1, 1},
...{0, 1, 0, 0},
...{1, 1, 1, 0},
...{1, 1, 0, 1},
...{0, 0, 0, 0}
};
// 进程最大需求资源数
RES_VECTOR VM[PN] = ...{
...{4, 1, 1, 1},
...{0, 2, 1, 1},
...{4, 2, 1, 0},
...{1, 1, 1, 1},
...{2, 1, 1, 0}
};
int SQ[PN]; // 安全序列
int fn = M_SafeTest(PN, RN, VA, VM, T, SQ);
if (fn == PN)
...{
printf("Status Safety! Safety Sequence: ");
for (int i=0; i<fn; i++)
printf("%c ", 'A'+SQ[i]);
printf(" ");
}
else
printf("Status Unsafety! ");
}
#include " Afx.h "
#define MAX_PROCESSES 100 // 最大进程数目
#define MAX_RESOURCES 10 // 最多资源数目
// 定义RES_VECTOR向量,便于程序的理解
typedef int RES_VECTOR[MAX_RESOURCES];
// 该程序完成的是银行家算法的核心算法部分,即:判断当前的状态是否
// 是安全的。根据银行家算法,在一个进程提出资源请求时,系统为了避
// 免死锁要对该行为进行判断。如果该行为导致后续系统状态安全,则系
// 统自动满足该请求;否则,如果该行为导致后续系统状态不安全,显然
// 系统要禁止当前的请求,也就是要阻塞请求资源的进程。而该程序就是
// 能判断一个状态[预分配状态]是否是安全状态,判断安全状态的函数是
// M_SafeTest,其他的都是辅助函数,所以采用了static来修饰。
// writed by Houjian Tang
// 判断系统状态是否安全
int M_SafeTest( int nPn, int nRn,
const RES_VECTOR * pVA,
const RES_VECTOR * pVM,
RES_VECTOR vT,
int * safety_seq);
// 获得一个“能执行完”进程
static int M_PreExcute( int nPn,
int nRn,
const RES_VECTOR * pVA,
const RES_VECTOR * pVM,
const RES_VECTOR vL,
const int * finished);
// 向量比较
static int LessEqul( int nRn, const RES_VECTOR Va, const RES_VECTOR Vb);
// 计算向量之差
static void GetSub(RES_VECTOR v, int nRn, const RES_VECTOR va, const RES_VECTOR vb);
// 计算向量之和
static void GetAdd(RES_VECTOR v, int nRn, const RES_VECTOR va, const RES_VECTOR vb);
// 算法测试函数
void Test_BanksAlgorithm_multi();
// 比较两个向量的大小,如果pA<=pB小于等于,返回非0, 否则返回0值
static int LessEqul( int nRn, const RES_VECTOR Va, const RES_VECTOR Vb)
... {
int i;
for (i=0; i<nRn; i++)
...{
if (Va[i] > Vb[i])
return FALSE;
}
return TRUE;
}
// 计算向量减法,即v=va-vb
static void GetSub(RES_VECTOR v, int nRn, const RES_VECTOR va, const RES_VECTOR vb)
... {
int i;
for (i=0; i<nRn; i++)
v[i] = va[i] - vb[i];
}
// 计算向量加法,即v=va+vb
static void GetAdd(RES_VECTOR v, int nRn, const RES_VECTOR va, const RES_VECTOR vb)
... {
int i;
for (i=0; i<nRn; i++)
v[i] = va[i] + vb[i];
}
// 查找一个可执行完进程,并返回进程编号,返回 -1 表示没有进程可以执行
// nPn ---- 进程数目
// nRn ---- 资源数目
// pVA ---- 进程已申请资源数
// pVM ---- 进程请求的最大资源数
// vL ---- 当前剩余的资源数目
// finished ---- “能执行完”标志
static int M_PreExcute( int nPn,
int nRn,
const RES_VECTOR * pVA,
const RES_VECTOR * pVM,
const RES_VECTOR vL,
const int * finished)
... {
RES_VECTOR vQ; // 还需要的资源数
int i;
// 在每一个进程中查找一个可以运行完的进程
for (i=0; i<nPn; i++)
...{
GetSub(vQ, nRn, pVM[i], pVA[i]);
if (!finished[i] && // 第一个条件:进程没有执行完
LessEqul(nRn, vQ, vL)) // 第二个条件:剩余资源可以满足该进程的执行
return i;
}
return -1;
}
// 判断当前的状态是否安全,同时给出安全序列
// 返回值:返回当前能够执行完的进程数目。
// nPn ---- 进程数目
// pA ---- 进程已申请资源数
// pM ---- 进程请求的最大资源数
// nT ---- 系统中所有资源数
// safety_seq ---- 进程执行的安全序列
int M_SafeTest( int nPn, int nRn,
const RES_VECTOR * pVA,
const RES_VECTOR * pVM,
RES_VECTOR vT,
int * safety_seq)
... {
int nFN = 0; // 已执行完的进程数量
int *finished = new int[nPn]; // 进程能执行完标志
int i;
// 系统剩余资源数
RES_VECTOR vL;
for (i=0; i<nRn; i++)
vL[i] = vT[i];
// 初始化“能运行完”标志和系统剩余资源数
for (i=0; i<nPn; i++)
...{
finished[i] = FALSE; // 初始化进程"能执行完"标志
GetSub(vL, nRn, vL, pVA[i]); // 初始化系统剩余资源数
}
// 主循环,每次找一个进程,找不到则终止退出
while (nFN < nPn)
...{
// 找到一个“可执行完”进程
int nPid = M_PreExcute(nPn, nRn, pVA, pVM, vL, finished);
if (nPid >= 0) // 查找成功
...{
GetAdd(vL, nRn, vL, pVA[nPid]); // 修改剩余资源数
safety_seq[nFN++] = nPid; // 添加到安全序列
finished[nPid] = TRUE; // 修改进程执行完标志
}
else
...{
// 如果查找失败,则直接退出
break;
}
}
delete []finished;
return nFN;
}
// 算法测试函数
void Test_BanksAlgorithm_multi()
... {
RES_VECTOR T = ...{6, 3, 4, 2}; // 系统拥有的资源数
#define PN 5 // 系统中进程数
#define RN 4 // 系统中拥有的资源种类数
// 进程已申请资源数
RES_VECTOR VA[PN] = ...{
...{3, 0, 1, 1},
...{0, 1, 0, 0},
...{1, 1, 1, 0},
...{1, 1, 0, 1},
...{0, 0, 0, 0}
};
// 进程最大需求资源数
RES_VECTOR VM[PN] = ...{
...{4, 1, 1, 1},
...{0, 2, 1, 1},
...{4, 2, 1, 0},
...{1, 1, 1, 1},
...{2, 1, 1, 0}
};
int SQ[PN]; // 安全序列
int fn = M_SafeTest(PN, RN, VA, VM, T, SQ);
if (fn == PN)
...{
printf("Status Safety! Safety Sequence: ");
for (int i=0; i<fn; i++)
printf("%c ", 'A'+SQ[i]);
printf(" ");
}
else
printf("Status Unsafety! ");
}