银行家算法##大魔王程序员

本文深入讲解银行家算法,包括算法中的关键数据结构如可利用资源向量、最大需求矩阵等,以及算法的具体步骤,如资源请求检查、资源分配试探、安全性算法执行等,通过代码实现帮助理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

银行家算法中的数据结构

(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个方能完成其任务.

银行家算法

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

(1)如果Request i[j] <= Need[i,j],便转向步骤(2);否则认为出错,因为它所需的资源数已超过它所宣布的最大值.

(2)如果Request i[j] <= Available[j],便转向步骤(3);否则,表示尚无足够的资源,p i须等待.

(3)系统试探的把资源分配给进程p i,并修改下面数据结构中的数值:

Available[j] = Available[j] - Request i[j];

Allocation[i,j] = Allocation[i,j] + Request i[j];

Need[i,j] = Need[i,j] - Request i[j];

(4)系统执行安全性算法,检查此次资源分配后系统是否处于安全状态.若安全,才正式将资源分配给进程p i,已完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程p i等待.

安全性算法

系统执行的安全性算法可描述如下:

(1)设置两个向量:1.工作向量work,他表示系统可提供给进程继续运行所需要的各类资源数目,它含有m个元素,在执行安全算法开始时,work = Available; 2.finish:它表示系统有足够的资源分配给进程,使之运行完成.开始时先做finish[i] = false;当有足够资源分配给进程时,再令finish[i] = true;

(2)从进程集合中找到一个能满足下述条件的进程:

1.finish[i]  = false;

2.Need[i,j] <= work[j];

若找到,执行步骤(3),否则,执行步骤(4)

(3)当进程p i获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:

work[j] = work[j] + Allocation[i,j];

finish[i] = true;

go to step 2

(4)如果所有进程的finish[i] = true都满足,则表示系统处于安全状态;否则,系统处于不安全状态

 

代码实现:

为了模仿计算机进程,编者使用随机值进行初始化

int  main()
{
	int progress ;
	int resource;
	bool flag = false;  //最后判断安全序列的标志
	bool flag1  = false;
	printf("请输入进程个数:");   
	int test = scanf("%d",&progress);   //行数
	while(test == 0)//输入异常机制
	{
		printf("输入有误,请重试!\n");
		fflush(stdin);    //清除缓存
		printf("请输入进程个数:");  
		test = scanf("%d",&progress);
	}
	printf("请输入资源个数:");
	int test1 = scanf("%d",&resource);   //列数
	while(test1 == 0)//输入异常机制
	{
		printf("输入有误,请重试!\n");
		fflush(stdin);    //清除缓存
		printf("请输入资源个数:");  
		test1 = scanf("%d",&resource);
	}

	int **Need = NULL;
	int **Allocation = NULL;
	int **Request = NULL;
	Need = OpenSpace2(Need,progress,resource);
	Allocation = OpenSpace2(Allocation,progress,resource);
	Request = OpenSpace2(Request,progress,resource);
	

	int *Available = (int *)malloc(sizeof(int)*resource);
	assert(Available != NULL);
	int *arr = (int*)calloc(progress,sizeof(int));         //保存安全序列
	assert(arr != NULL);

	Init(Need,Allocation,Request,Available,progress,resource);
	Show(Need,Allocation,Request,Available,progress,resource);
	flag1 = Safe(Need,Allocation,Request,Available,progress,resource,arr);
	if(!flag1)
	{
		Delete(Need,Allocation,Request,Available,progress,arr);
		return 0;
	}
	flag = Bank(Need,Allocation,Request,Available,progress,resource,arr);

	if(flag)
	{
		printf("安全序列为:\n");
		for(int i =0; i< progress;i++)
		{
			printf("P%d ",arr[i]);
		}
		printf("\n");
	}

	//Show(Need,Allocation,Request,Available,progress,resource);
	Delete(Need,Allocation,Request,Available,progress,arr);
	return 0;
}
bool Bank(int **Need,int **Allocation,int **Request,int * Available,int progress,int resource,int *arr)
{
	assert(Need != NULL && Allocation != NULL && Request != NULL);
	//bool *finish =(bool*)malloc(sizeof(bool)*progress);
	bool flag = false;
	//assert(finish != NULL);
	int k;
	printf("请输入请求向量进程号(从0开始):");
	int test = scanf("%d",&k);
	while(test == 0 || k >=progress || k < 0 )//输入异常机制
	{
		printf("输入有误,请重试!\n");
		fflush(stdin);    //清除缓存
		printf("请输入请求向量进程号(从0开始):");  
		test = scanf("%d",&k);
	}
	printf("请输入请求向量(回车分隔):\n");
	for(int i = 0; i < resource ;i++)
	{
		int test1 = scanf("%d",&Request[k][i]); 
		if(test1 == 0)   //输入异常机制
		{
			fflush(stdin);    //清除缓存
			printf("输入有误,请重新输入!\n");
			i--;
		}
		if(Request[k][i] > Need[k][i] )
		{
			printf("输入有误,请重新输入!\n");
			i--;
		}
	}
	int j = 0;	
	for( j = 0; j < resource;j++)
	{
		if(Request[k][j] > Available[j])
		{
			printf("尚无足够资源,P%d需等待\n",k);
			return false;
		}
		flag = true;	
	}
	if(flag)
	{
		for( j = 0;j < resource;j++)
		{
			Available[j] -=Request[k][j];
			Allocation[k][j] += Request[k][j];
			Need[k][j] -= Request[k][j];
		}
		if(!Safe(Need,Allocation,Request,Available,progress,resource,arr))//如果不安全
		{
			flag = false;
			for( j = 0; j < resource;j++)//恢复资源
			{
				Available[j] +=Request[k][j];
				Allocation[k][j] -= Request[k][j];
				Need[k][j] += Request[k][j];	
			}	
		}
	}
	
	if(flag == false)
	{		
		printf("系统处于不安全状态\n");
		return false;
	}
	else
	{	
		printf("系统处于安全状态\n");
		return true;
	}
}
bool Safe(int **Need,int **Allocation,int **Request,int * Available,int progress,int resource,int *arr)
{
	assert(Need != NULL && Allocation != NULL && Available != NULL);
	int k = 0;      //arr的下标
	int *Work = (int *)malloc(sizeof(int)*resource);
	assert(Work != NULL);
	for(int i = 0; i< resource;i++)
	{
		Work[i] = Available[i];
	}
	bool *finish =(bool*)malloc(sizeof(bool)*progress);
	assert(finish != NULL);
	for(int i = 0; i< progress;i++)
	{
		finish[i] = false;
	}
	//Show(Need,Allocation,Request,Available,progress,resource);
	for(int i = 0;i < progress; i++)
	{
		if(!finish[i])
		{
			int j;
			for( j = 0; j < resource;j++)
			{
				if(Need[i][j] > Work[j])  
				{
					break;    //判断下一个进程是否安全
				}
				if(j+1 == resource) //即Need中[i]向量,所有的值都小于Work向量的值     j为下标,resource为资源数
				{
					finish[i] = true;
					arr[k++] = i;
					for(j = 0;j < resource;j++)
					{
						Work[j] += Allocation[i][j];
					}
					i = -1;   //重新开始扫描
				}
			}
		}
	}
	for(int i = 0; i < progress; i++)
	{
		if(!finish[i])
		{
			free(Work);
			free(finish);
			printf("此时处于不安全的状态\n");
			return false;
		}
	}
	free(Work);
	free(finish);
	printf("此时处于安全的状态\n");
	return true;
}
void Init(int **Need,int **Allocation,int **Request,int * Available,int progress,int resource)//初始化
{
	assert(Need != NULL && Allocation != NULL);
	srand((unsigned)time( NULL ) );  	
	for(int i = 0; i < progress;i++)		
	{
		for(int j  = 0 ;j< resource; j++)
		{
			Need[i][j] = rand()%8+0;
			Allocation[i][j] = rand()%7+0;
			Request[i][j] = 0;
		}
	}
	for(int i = 0; i < resource;i++)
	{
		Available[i] = rand()%10+5;
	}
}
void Show(int **Need,int **Allocation,int **Request ,int * Available,int progress,int resource)
{
	assert(Need != NULL && Allocation != NULL);
	printf("需求矩阵:\t\t分配矩阵:\t\t需求矩阵:\n");
	for(int i = 0; i < progress;i++)		
	{
		for(int j  = 0 ;j< resource; j++)
		{
			printf("%d ",Need[i][j]);
		}
		printf("\t\t\t");
		for(int j  = 0 ;j< resource; j++)
		{
			printf("%d ",Allocation[i][j]);
		}
		printf("\t\t\t");
		for(int j  = 0 ;j< resource; j++)
		{
			printf("%d ",Request[i][j]);
		}
		printf("\n");
	}
	printf("可利用资源向量:\n");
	for(int i = 0; i < resource;i++)
	{
		printf("%d ",Available[i]);
	}
	printf("\n");
}

依次拼接即可使用,如果没有<vdl.h>的插件,直接屏蔽即可.

如果在使用中发现问题,望指出.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值