银行家算法(多项资源)

银行家算法(单项资源)  

文中给出了单项资源的银行家算法。本文给出的是多种资源的银行家算法。在本质上,单项资源的银行家算法和多种资源的银行家算法没有什么区别,只是书写起来有一点点不同(用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 
= {6342};          // 系统拥有的资源数

#define PN   5              // 系统中进程数
#define RN   4              // 系统中拥有的资源种类数
    
// 进程已申请资源数
    RES_VECTOR VA[PN] = {
        
{3011},
        
{0100},
        
{1110},
        
{1101},
        
{0000}
    }
;  

    
// 进程最大需求资源数
    RES_VECTOR VM[PN] = {
        
{4111},
        
{0211},
        
{4210},
        
{1111},
        
{2110}
    }
;  

    
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! ");
}

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值