一、数据结构的定义
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) ;
}