【银行家算法实现源码】

银行家算法是一种避免死锁的策略,由艾兹格·迪杰斯特拉提出。该算法通过设置四个数据结构(Available、Max、Allocation、Need)来确保系统安全。在资源分配前,系统会检查分配是否安全,只有在安全的情况下才会分配资源。文章提供了一个银行家算法的C语言实现,并展示了如何检查安全性及处理资源申请。
摘要由CSDN通过智能技术生成

目录

1、什么是银行家算法

2、题目

3、解决过程 

4、为了实现银行家算法,在系统中必须设置这样四个数据结构:

5、将银行家算法的逻辑转化为自然语言:

6、源码:

 7、运行结果

1、什么是银行家算法


  银行家算法(Banker’s Algorithm)是一个避免死锁(Deadlock)的著名算法,是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的一种避免死锁产生的算法。它以银行借贷系统的分配策略为基础,判断并保证系统的安全运行。
  在银行中,客户申请贷款的数量是有限的,每个客户在第一次申请贷款时要声明完成该项目所需的最大资金量,在满足所有贷款要求时,客户应及时归还。银行家在客户申请的贷款数量不超过自己拥有的最大值时,都应尽量满足客户的需要。在这样的描述中,银行家就好比操作系统,资金就是资源,客户就相当于要申请资源的进程。
  银行家算法是一种最有代表性的避免死锁的算法。在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。为实现银行家算法,系统必须设置若干数据结构。

2、题目

3、解决过程 

 

4、为了实现银行家算法,在系统中必须设置这样四个数据结构:

Available向量:系统中可利用的资源数目

Max矩阵:每个进程对每种资源的最大需求

Allocation矩阵:每个进程已分配的各类资源的数目

Need矩阵:每个进程还需要的各类资源数 其中三个矩阵间存在下述关系: Need[i,j] = Max[i,j] - allocation[i, j]

5、将银行家算法的逻辑转化为自然语言:

设Requesti是进程Pi的请求向量,如果Requesti[j]=K,表示进程Pi需要K个Rj类型的资源。当Pi发出资源请求后,系统按下述步骤进行检查:

(1) 若 Requesti[j] ≤ Need[i,j],转向(2),否则认为出错(因为它所需的资源数目已超过它所宣布的最大值)。

(2) 若 Requesti[j] ≤ Available[j],转向(3),否则须等待(表现为进程Pi受阻)。 

(3) 系统尝试把资源分配给进程Pi,并修改下面数据结构中的数值: Available[j] = Available[j] – Requesti[j] Allocation[i,j] = Allocation[i,j] + Requesti[j] Need[i,j] = Need[i,j] –Requesti[j] (4) 试分配后,执行安全性算法,检查此次分配后系统是否处于安全状态。若安全,才正式分配;否则,此次试分配作废,进程Pi等待。

6、源码:

//#include<iostream>
#include<stdio.h>
//using namespace std;
//p进程数 
int p ;
//r资源种类
int r ;
//最大需求矩阵
int maxs[10][10]={{0,0,4,4},{2,7,5,0},{3,6,10,10},{0,9,8,4},{0,6,6,10}}; 
//分配矩阵
int allocation[10][10]={{0,0,3,2},{1,0,0,0},{1,3,5,4},{0,3,3,2},{0,0,1,4}}; 
//需求矩阵
int need[10][10]={{0,0,1,2},{1,7,5,0},{2,3,5,6},{0,6,5,2},{0,6,5,6}}; 
//可用资源向量
int available[10]={1,6,2,2}; 
//请求向量当前进程对各类资源的申请量,算法的入口参数
int request[10]; 
//输入函数
void infInput()
{
int i,j;

//cout<<"请输入最大需求矩阵 max\n";
printf("请输入最大需求矩阵");
for(i=0; i<p; i++)
{
for(j=0; j<r; j++)
{
	
//cin>>maxs[i][j];
scanf("%d",&maxs[i][j]);
}
}

//cout<<"请输入分配矩阵 allocation\n";
printf("请输入分配矩阵 allocation\n");

for(i=0; i<p; i++)
{
for(j=0; j<r; j++)
{
	
//cin>>allocation[i][j];
scanf("%d",&allocation[i][j]);
}
}

//cout<<"请输入需求矩阵 need\n";
printf("请输入需求矩阵 need\n");
for(i=0; i<p; i++)
{
for(j=0; j<r; j++)
{
	
//cin>>need[i][j];
scanf("%d",&need[i][j]);

}
}

//cout<<"请输入可用资源向量 available\n";
printf("请输入可用资源向量 available\n");

for(i=0; i<r; i++)
{
	
//cin>>available[i];
scanf("%d",&available[i]);
}
}//比较函数
//比较进程为 m 中的元素全大于 n 中的元素返回 1,否则返回 0
int compare(int m[],int n[])
{
int i;
for(i=0; i<r; i++)
{
if(m[i]<n[i])
{
return 0;
}
}
return 1;
}
//安全性检验函数,检测是否存在安全序列
int stest()
{
	int i,j,k,l,flag=0;
	int finish[p];
	int work[r];
	for(i=0; i<p; i++)
	{
	finish[i]=0;
	//vis 为 1 即表示 available 满足第 i 进程的资源需要
	}
for(i=0; i<r; i++)
	{
	work[i]=available[i];
	}
	
	
//cout<<"分配序列: \n";
//cout<<" allocation need avilable"<<endl;
printf("分配序列: \n");
printf("allocation need avilable");

for(k=0; k<p; k++)
{
	for(i=0; i<p; i++)
	{
	if(finish[i]==1)
		{
		continue;
		}
	else{
		//available>=need
		if(compare(work,need[i]))
			{
			finish[i]=1;
			
			
			//cout<<'\n'<<"进程"<<i+1<<'\t';
			printf("\n进程%d\t",i+1);
			
			flag=1;
			for (j =0; j<r; j++)
			{
				printf(" %2d ", allocation[i][j]);
			}
			
			//cout<<" ";
			printf(" ");
			
			for (j = 0; j < r; j++)
			{
				printf(" %2d ", need[i][j]);
			}
			
			//cout<<" ";
			printf(" ");
			
			for (j = 0; j <r; j++)
			{
				printf(" %2d ", work[j] +allocation[i][j]);
			}
			for(l=0; l<r; l++)
			{
				work[l]=work[l]+allocation[i][l];
				//进程完成,释放资源
			}
			break;
		}
	if(i<p)
		continue;	
	
	}
if(flag==1)
{
break;
}

}
}


//cout<<'\n';
printf("\n");

for(l=0; l<p; l++)
{
if(finish[l]==0)
{
//不存在安全序列
return 0;
}
}
//存在安全序列
return 1;
}
//申请进程后的安全性检验函数
void rtest(int n)
{
int j;
//n=n-1;
if(compare(available,request)&&compare(need[n-1],request))//available>=request并且 need >=request
{
for(j=0; j<r; j++)
{
allocation[n-1][j]=allocation[n-1][j]+request[j];
need[n-1][j]=need[n-1][j]-request[j];
available[j]=available[j]-request[j];
}
if(stest())
{
	
	
//cout<<"允许"<<n<<"进程申请资源! \n";
printf("允许%d进程申请资源! \n",n);

}
else
{
	
	
//cout<<"不允许"<<n<<"进程申请资源! \n";
printf("不允许%d进程申请资源! \n",n);

for(j=0; j<r; j++)
{
allocation[n-1][j]=allocation[n-1][j]-request[j];
need[n-1][j]=need[n-1][j]+request[j];
available[j]=available[j]+request[j];
}
}
}
else
{
	
	
//cout<<"申请资源量越界! \n";
printf("申请资源量越界! \n");

}
}
int main()
{
int i,n; //n-第 n 个资源申请
 

//cout<<"请输入进程数: ";
printf("请输入进程数: ");

//cin>>p;
scanf("%d",&p); 

//cout<<"请输入资源种类数: ";cin>>r;
printf("请输入资源种类数: ");
scanf("%d",&r); 


//默认状态 4、 3
//infInput();//输入函数

if(stest()==1)
{
	
	
//cout<<"存在安全序列,初始状态安全。 \n";
printf("存在安全序列,初始状态安全。 \n");

}
else
{
	
	
//cout<<"不存在安全序列,初始状态不安全。 \n";
printf("不存在安全序列,初始状态不安全。 \n");

}


//cout<<"请输入发出请求向量 request 的进程编号: ";
//cin>>n;
//cout<<"请输入请求向量 request\n";
printf("请输入发出请求向量 request 的进程编号: ");
scanf("%d",&n); 
printf("请输入请求向量 request\n");


for(i=0; i<r; i++)
{
	
//cin>>request[i];
scanf("%d",&request[i]); 

}
rtest(n);
return 0;
}

 7、运行结果

银行家算法是避免死锁的一种重要方法,本程序用java编程语言对其进行了实现。 当用户申请一组资源时,系统必须做出判断,如果把这些资源分出去,系统是否还处于安全状态。 若是,就可以分出这些资源;否则,该申请暂不予满足。 1.数据结构 假设有M个进程N类资源,则有如下数据结构: MAX[M*N] M个进程对N类资源的最大需求量 AVAILABLE[N] 系统可用资源数 ALLOCATION[M*N] M个进程已经得到N类资源的资源量 NEED[M*N] M个进程还需要N类资源的资源量 2.银行家算法 设进程I提出请求Request[N],则银行家算法按如下规则进行判断。 (1)如果Request[N]<=NEED[I,N],则转(2);否则,出错。 (2)如果Request[N]<=AVAILABLE,则转(3);否则,出错。 (3)系统试探分配资源,修改相关数据: AVAILABLE=AVAILABLE-REQUEST ALLOCATION=ALLOCATION+REQUEST NEED=NEED-REQUEST (4)系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。 3.安全性检查 (1)设置两个工作向量WORK=AVAILABLE;FINISH[M]=FALSE (2)从进程集合中找到一个满足下述条件的进程, FINISH[i]=FALSE NEED<=WORK 如找到,执行(3);否则,执行(4) (3)设进程获得资源,可顺利执行,直至完成,从而释放资源。 WORK=WORK+ALLOCATION FINISH=TRUE GO TO 2 (4)如所有的进程Finish[M]=true,则表示安全;否则系统不安全。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值