银行家算法

一、关于死锁

1.死锁基本概念

两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。
此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

2.死锁必备条件

(1)互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,
则请求者只能等待,直至占有资源的进程用毕释放。
(2)请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,
但又对自己已获得的其它资源保持不放。
(3)不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
(4)环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待
一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。

3.死锁避免

	避免死锁算法中最有代表性的算法是Dijkstra E.W于1968年提出的银行家算法。
	银行家算法顾名思义是来源于银行的借贷业务,一定数量的本金要应多个客户的借贷周转,为了防止银行家资金无法周转而倒闭,
对每一笔贷款,必须考察其是否能限期归还。在操作系统中研究资源分配策略时也有类似问题,系统中有限的资源要供多个进程使用,
必须保证得到的资源的进程能在有限的时间内归还资源,以供其他进程使用资源。如果资源分配不得到就会发生进程循环等待资源,则进程
都无法继续执行下去的死锁现象。
	把一个进程需要和已占有资源的情况记录在进程控制中,假定进程控制块PCB其中“状态”有就绪态、等待态和完成态。当进程在处于
等待态时,表示系统不能满足该进程当前的资源申请。“资源需求总量”表示进程在整个执行过程中总共要申请的资源量。显然,每个进程的
资源需求总量不能超过系统拥有的资源总数,银行算法进行资源分配可以避免死锁。

二、数据结构

可用资源向量available:这是一个含有m个元素的数组,其中的每一个元素代表一类可利用资源数目。
最大需求矩阵max:它是一个的矩阵,定义了系统中n个进程中得每一个进程对类资源的最大需求。
可分配矩阵allocation:这也一个的矩阵,定义了系统中每一类资源当前已分配给每一进程的资源数。
需求矩阵need:这表示每一个进程尚需的各类资源数。need[i][j]=max[i][j]-allocation[i][j]。

三、变量说明

可用资源向量available[3];
最大需求矩阵max[4][3];
可分配矩阵allocation[4][3];
需求矩阵need[4][3];
进程状态标识finish[4];

四、流程图

银行家算法的流程图

银行家算法的流程图

五、源代码

#include<stdio.h>
#define M 4 //进程数
#define N 3 //资源种类数
int available[3]={0,0,0}; //各进程可利用的资源情况
int max[4][3]={{0,0,0},{0,0,0},{0,0,0},{0,0,0}};          
//各进程最大需求的资源情况
int allocation[4][3]={{0,0,0},{0,0,0},{0,0,0},{0,0,0}};  
 //各进程已经分配的资源情况
int need[4][3]={{0,0,0},{0,0,0},{0,0,0},{0,0,0}};         
//各进程仍需要的资源情况
int request[3]={0,0,0}; //某进程请求的资源情况
/***************输入初始的资源状况***************/
void input()
{
	int i=0,j=0;
	printf("\t\t\t\tA  B  C\n");
	printf("请输入进程0对3类资源的最大需求:");
	for(j=0;j<3;j++)
	{
		scanf("%d",&max[0][j]);
	}
	printf("\n");
	printf("请输入进程1对3类资源的最大需求:");
	for(j=0;j<3;j++)
	{
		scanf("%d",&max[1][j]);
	}
	printf("\n");
	printf("请输入进程2对3类资源的最大需求:");
	for(j=0;j<3;j++)
	{
		scanf("%d",&max[2][j]);
	}
	printf("\n");
	printf("请输入进程3对3类资源的最大需求:");
	for(j=0;j<3;j++)
	{
		scanf("%d",&max[3][j]);
	}
	printf("\n");
	printf("请输入进程0已分配的3类资源量:");
    for(j=0;j<3;j++)
	{
		scanf("%d",&allocation[0][j]);
	}
	printf("\n");
	printf("请输入进程1已分配的3类资源量:");
    for(j=0;j<3;j++)
	{
		scanf("%d",&allocation[1][j]);
	}
	printf("\n");
	printf("请输入进程2已分配的3类资源量:");
    for(j=0;j<3;j++)
	{
		scanf("%d",&allocation[2][j]);
	}
	printf("\n");
	printf("请输入进程3已分配的3类资源量:");
    for(j=0;j<3;j++)
	{
		scanf("%d",&allocation[3][j]);
	}
	printf("\n");
	printf("请输入可利用的3类资源量:");
    for(j=0;j<3;j++)
	{
		scanf("%d",&available[j]);
	}
	for(i=0;i<4;i++)
		for(j=0;j<3;j++)
		{
			need[i][j]=max[i][j]-allocation[i][j];
		}
	printf("\n");
}    
/***************显示当前的资源状况***************/
void output()
{   
	int i=0,j=0;
	printf("该时刻3类资源的分配情况如下:\n");
	printf("\tMAX\t\tALOCAT\t\tNEED\t\tAVAILABLE\n");
	printf("进程0:\t");
	for(j=0;j<3;j++)
	{
		printf("%d  ",max[0][j]);
	}
	printf("\t");
	for(j=0;j<3;j++)
	{
		printf("%d  ",allocation[0][j]);
	}
	printf("\t");
	for(j=0;j<3;j++)
	{
		printf("%d  ",need[0][j]);
	}
	printf("\t");
	for(j=0;j<3;j++)
	{
		printf("%d  ",available[j]);
	}
	printf("\n");
	printf("进程1:\t");
	for(j=0;j<3;j++)
	{
		printf("%d  ",max[1][j]);
	}
	printf("\t");
	for(j=0;j<3;j++)
	{
		printf("%d  ",allocation[1][j]);
	}
	printf("\t");
	for(j=0;j<3;j++)
	{
		printf("%d  ",need[1][j]);
	}
	printf("\n");
	printf("进程2:\t");
	for(j=0;j<3;j++)
	{
		printf("%d  ",max[2][j]);
	}
	printf("\t");
	for(j=0;j<3;j++)
	{
		printf("%d  ",allocation[2][j]);
	}
	printf("\t");
	for(j=0;j<3;j++)
	{
		printf("%d  ",need[2][j]);
	}
	printf("\n");
	printf("进程3:\t");
	for(j=0;j<3;j++)
	{
		printf("%d  ",max[3][j]);
	}
	printf("\t");
	for(j=0;j<3;j++)
	{
		printf("%d  ",allocation[3][j]);
	}
	printf("\t");
	for(j=0;j<3;j++)
	{
		printf("%d  ",need[3][j]);
	}
	printf("\n");
} 
/***************给某进程分配资源***************/
void change(int n)
{
	int j;
	for(j=0;j<N;j++)
	{
		available[j]=available[j]-request[j];
		allocation[n][j]=allocation[n][j]+request[j];
		need[n][j]=need[n][j]-request[j];
	}
}
/***************找出占用资源最多的进程***************/
int findmany()
{
	int i=0,j=0,k=0,l=0;
	i=allocation[0][0]+allocation[0][1];
	i+=allocation[0][2];
	j=allocation[1][0]+allocation[1][1];
	j+=allocation[1][2];
	k=allocation[2][0]+allocation[2][1];
	k+=allocation[2][2];
	l=allocation[3][0]+allocation[3][1];
	l+=allocation[3][2];
	if(i>=j)
	{
		if(i>=k)
		{
			if(i>=l)
				return 0;
			else
				return 3;
		}
		else
		{
			if(k>=l)
				return 2;
			else
				return 3;
		}
	}
	else
	{
		if(j>=k)
		{
			if(j>=l)
				return 1;
			else
				return 3;
		}
		else
		{
			if(k>=l)
				return 2;
			else
				return 3;
		}
	}
}
/***************找出需要资源最少的进程***************/
int findfew()
{
	int i=0,j=0,k=0,l=0;
	i=need[0][0]+need[0][1];
	i+=need[0][2];
	j=need[1][0]+need[1][1];
	j+=need[1][2];
	k=need[2][0]+need[2][1];
	k+=need[2][2];
	l=need[3][0]+need[3][1];
	l+=need[3][2];
	if(i<=j)
	{
		if(i<=k)
		{
			if(i<=l)
				return 0;
			else
				return 3;
		}
		else
		{
			if(k<=l)
				return 2;
			else
				return 3;
		}
	}
	else
	{
		if(j<=k)
		{
			if(j<=l)
				return 1;
			else
				return 3;
		}
		else
		{
			if(k<=l)
				return 2;
			else
				return 3;
		}
	}
}
/***************安全性检测***************/
int checksafe(int n)
{
	int work[3],finish[M],que[M];
	int i=0,k=0;
	for(i=0;i<M;i++)
        finish[i]=false;
	for(;;)
	{
		work[0]=available[0];
        work[1]=available[1];
		work[2]=available[2];
		i=n;
		while(i<M)
		{
			if(finish[i]==false&&need[i][0]<=work[0]&&need[i][1]<=work[1]&&need[i][2]<=work[2])
			{
				work[0]+=allocation[i][0];
				work[1]+=allocation[i][1];
				work[2]+=allocation[i][2];
				finish[i]=true;
				que[k]=i;
				k++;
				i=0;
			}
			else
				i++;
		}
		for(i=0;i<M;i++)
			if(finish[i]==false)
			{
				printf("存在死锁!\n");
                return 1;
				break;
			}
		break;
	}
	printf("\n");
	printf("检测结果:不存在死锁!\n");
	printf("安全序列为:");
	for(i=0;i<M;i++)
		printf("%d\t",que[i]);
	printf("\n");
	return 0;
}
/***************主函数***************/
void main()
{
	int m=0,n=0,i=0,j=0;
	printf("\t\t\t死锁的检测与解除\n");
    printf("\n");
    input();
	output();
		printf("请输入请求资源的进程号:");
        scanf("%d",&n);
		printf("\n");
			printf("请输入进程%d对3类资源的需求量:",n);
	        for(j=0;j<3;j++)
				scanf("%d",&request[j]);
    printf("\n");
	change(n);
	if(checksafe(n))
	{
    check:
	{
		m=findmany();
		printf("\n");
		printf("撤销进程%d所占用的资源!\n",m);
        for(j=0;j<3;j++)
		{
			available[j]+=allocation[m][j];
			need[m][j]+=allocation[m][j];
			allocation[m][j]=0;
		}
		n=findfew();
		for(j=0;j<3;j++)
		{request[j]=need[n][j];	}
		change(n);
		if(checksafe(n))
		    goto check;
	}    
	}
	output();
}                     

六、运行结果

无死锁的输入输出集

无死锁的输入输出集

有死锁的输入输出集

有死锁的输入输出集

有连续死锁的输入输出集

有连续死锁的输入输出集

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

絆馶煙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值