银行家算法避免死锁C/C++

一、数据结构的定义
1)可利用资源向量Available
是个含有m个元素的数组,其中的每一个元素代表一类可利用的资源数目。如果Available[j]=K,则表示系统中现有Rj类资源K个。

2)最大需求矩阵Max
这是一个n×m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max[i,j]=K,则表示进程i需要Rj类资源的最大数目为K。

3)分配矩阵Allocation
这也是一个n×m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。如果Allocation[i,j]=K,则表示进程i当前已分得Rj类资源的 数目为K。

4)需求矩阵Need。
这也是一个n×m的矩阵,用以表示每一个进程尚需的各类资源数。如果Need[i,j]=K,则表示进程i还需要Rj类资源K个,方能完成其任务。
Need[i,j]=Max[i,j]-Allocation[i,j]

二、算法描述
在避免死锁的方法中,所施加的限制条件较弱,有可能获得令人满意的系统性能。在该方法中把系统的状态分为安全状态和不安全状态,只要能使系统始终都处于安全状态,便可以避免发生死锁。
银行家算法的基本思想是分配资源之前,判断系统是否是安全的;若是,才分配。它是最具有代表性的避免死锁的算法。
设进程cusneed提出请求REQUEST [i],则银行家算法按如下规则进行判断。
(1)如果REQUEST [cusneed] [i]<= NEED[cusneed][i],则转(2);否则,出错。
(2)如果REQUEST [cusneed] [i]<= AVAILABLE[i],则转(3);否则,等待。
(3)系统试探分配资源,修改相关数据:
AVAILABLE[i]-=REQUEST[cusneed][i];
ALLOCATION[cusneed][i]+=REQUEST[cusneed][i];
NEED[cusneed][i]-=REQUEST[cusneed][i];
(4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。
安全性检查算法
(1)设置两个工作向量Work=AVAILABLE;FINISH
(2)从进程集合中找到一个满足下述条件的进程,
FINISH==false;
NEED<=Work;
如找到,执行(3);否则,执行(4)
(3)设进程获得资源,可顺利执行,直至完成,从而释放资源。
Work=Work+ALLOCATION;
Finish=true;
GOTO 2
(4)如所有的进程Finish= true,则表示安全;否则系统不安全。

三、算法的具体实现

/*
 *通过银行家算法预防进程死锁
 *防止进入不安全状态
 */
#include<stdio.h>
#define RESOURCE_NUM 3
#define PROCESS_NUM 5
/*
 *对三种可分配资源定义结构体
 */
typedef struct
{
    int a ;
    int b ;
    int c ;
} Resource ;

/*
 *对各进程的资源进行初始化
 */
   Resource available = {3 , 3 , 2}; //3种资源
   Resource x_max[PROCESS_NUM] = {{7 , 5 , 3} , {3 , 2 , 2} , {9 , 0 , 2} , {2 , 2 , 2} , {4 , 3 , 3}}; //最大需要的资源
   Resource allocation[PROCESS_NUM] = {{0 , 1 , 0} , {2 , 0 , 0} , {3 , 0 , 2} , {2 , 1 , 1} , {0 , 0 , 2}}; //已经占有的资源
   Resource need[PROCESS_NUM] = {{7 , 4 , 3} , {1 , 2 , 2} , {6 , 0 , 0} , {0 , 1 , 1} , {4 , 3 , 1}} ; //还需要的资源

/*
 *进行资源的尝试性分配
 */
bool tryToDistribution(int process_id , Resource *r) ;

/*
 *分配资源不安全时进行回滚
 */
void callBack(int process_id , Resource *r) ;

/*
 *进行分配后的安全性检查
 */
 bool checkSecurity() ;

 /*
  *进行当前资源状态的输出操作
  */
void outputResource() ;
/*
 *测试主函数
 */
int main()
{
    outputResource() ;

    int process_id , choice ;
    Resource r ;
    while(true)
    {
        printf("Wheather go on deliever : (0 or 1) ") ;
        scanf("%d" , &choice) ;
        if(choice)
        {
          printf("Please input request : (x and request) ") ;
          scanf("%d %d %d %d" , &process_id , &r.a , &r.b , &r.c) ;
          if(tryToDistribution(process_id , &r))
          {
              if(checkSecurity())
              {
                  printf("Resource deliever success ! \n") ;
                  //分配完成时进行资源的回收
                  if(!need[process_id].a)
                  {
                      available.a += allocation[process_id].a ;
                  }
                  if(!need[process_id].b)
                  {
                      available.b += allocation[process_id].b ;
                  }
                  if(!need[process_id].c)
                  {
                      available.c += allocation[process_id].c ;
                  }
                  outputResource() ;
              }
              else
              {
                  printf("The resource deliever is not safe ! \n") ;
                  callBack(process_id , &r) ;
              }
          }
          else
          {
              continue ;
          }
        }
        else
        {
            break ;
        }
    }
    printf("Handle Over ! \n") ;

    return 0 ;
}

/*
 *进行资源的尝试性分配
 */
bool tryToDistribution(int process_id , Resource *r)
{
    //判断分配的资源是否合法
    if(r->a > need[process_id].a || r->b > need[process_id].b || r->c > need[process_id].c)
    {
        printf("The dilever is more than need ! \n") ;
        return false ;
    }
    if(r->a > available.a || r->b > available.b || r->c > available.c)
    {
        printf("The resource is not enough ! \n") ;
        return false ;
    }

    available.a -= r->a ;
    available.b -= r->b ;
    available.c -= r->c ;

    allocation[process_id].a += r->a ;
    allocation[process_id].b += r->b;
    allocation[process_id].c += r->c ;

    need[process_id].a -= r->a ;
    need[process_id].b -= r->b ;
    need[process_id].c -= r->c ;
    return true ;
}

/*
 *进行资源的安全性检查
 */
 bool checkSecurity()
 {
    bool finish[5] = {false} ;
    Resource work = available ;
    while(true)
    {
        int pro_id , i ; // 记录满足条件的进程
        //寻找满足分配条件的进程
        for(i = 0 ; i < PROCESS_NUM ; i++)
        {
          if(!finish[i])
          {
              //减产满足条件的进程
             if(need[i].a <= work.a && need[i].b <= work.b && need[i].c <= work.c)
            {
                pro_id = i ;
                break ;
            }
          }
        }
        if(i == PROCESS_NUM)
        {
            for(int j = 0 ; j < i ; j++)
            {
                if(!finish[j])
                {
                    return false ;
                }
            }
            return true ;
        }

        work.a += allocation[i].a ;
        work.b += allocation[i].b ;
        work.c += allocation[i].c ;

        finish[pro_id] = true ;
    }
    return false ;
 }

 /*
 *分配资源不安全时进行回滚
 */
void callBack(int process_id , Resource *r)
{
    available.a += r->a ;
    available.b += r->b ;
    available.c += r->c ;

    allocation[process_id].a -= r->a ;
    allocation[process_id].b -= r->b;
    allocation[process_id].c -= r->c ;

    need[process_id].a += r->a ;
    need[process_id].b += r->b ;
    need[process_id].c += r->c ;
}

 /*
  *进行当前资源状态的输出操作
  */
void outputResource()
{
    printf("       ---MAX---   Allocation -----Need---- \n") ;
    printf("       a   b   c |  a   b   c |  a   b   c\n") ;
    for(int i = 0 ; i < PROCESS_NUM ; i++)
    {
            printf("P%d : " , i) ;
            printf("%3d %3d %3d |" , x_max[i].a , x_max[i].b , x_max[i].c) ;
            printf("%3d %3d %3d |" , allocation[i].a , allocation[i].b , allocation[i].c) ;
            printf("%3d %3d %3d " , need[i].a , need[i].b , need[i].c) ;
        printf("\n") ;
    }
    printf("The available resource now : a : %d  b : %d  c : %d \n" , available.a , available.b , available.c) ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值