银行家算法(单项资源)
文中给出了单项资源的银行家算法。本文给出的是多种资源的银行家算法。在本质上,单项资源的银行家算法和多种资源的银行家算法没有什么区别,只是书写起来有一点点不同(用C的语法,如果用C++的语法几乎可以写得一模一样)。有关银行家算法的问题大家可以看银行家算法(单项资源) 内容,在此不在赘述。此处只给出源码供大家参考。
不过里面有一个定义
// 定义RES_VECTOR向量,便于程序的理解 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! ");}
