银行家算法(Banker's Algorithm)

银行家算法是用来避免死锁的一种算法。每当有一个新进程,就需要给出它所需资源的最大数目,如果此数目超过系统拥有资源数,则申请失败。

对于进程的每一组请求,首先检查系统是否有足够的资源分配给它,如果有,则进一步计算,当系统分配资源后,是否处于不安全状态,如果处于不安全状态,则拒绝分配。

《银行家算法(Banker's Algorithm)》

《银行家算法(Banker's Algorithm)》

//main.cpp
#include "Bank.h"

int main()
{
	extern int num;
	extern int ProcessCount;
	extern int *recorder;

	//初始化
	init();

	//银行家算法
	bank();

	if (num == ProcessCount)
	{
		std::cout << "安全序列: ";
		for (int i = 0; i < num; ++i)
			std::cout << recorder[i] << " ";
		std::cout << std::endl;
	}
	else
		std::cout << "找不到安全序列" << std::endl;

	delete[] recorder;

	return 0;
}

//bank.h
#ifndef BANK_H_
#define BANK_H_

#include <iostream>

//初始化数据结构与请求向量
void init();

//银行家算法
void bank();

//安全性算法
bool safe();

#endif

//bank.cpp
#include "Bank.h"

int *Available = NULL;		//可用资源向量
int **Max = NULL;			//最大需求矩阵
int **Allocation = NULL;	//分配矩阵
int **Need = NULL;			//需求矩阵

int **Request = NULL;		//请求向量

int SourceCount = NULL;	//资源种类数
int ProcessCount = NULL;	//进程数目

int *recorder = NULL;		//记录安全序列
int num = 0;

//初始化数据结构与请求向量
void init()
{
	std::cout << "请输入系统资源种类数目: ";
	std::cin >> SourceCount;
	std::cout << "请输入进程数目: ";
	std::cin >> ProcessCount;

	recorder = new int[ProcessCount];
	for (int i = 0; i < ProcessCount; ++i)
		recorder[i] = -1;

	Request = new int*[ProcessCount];
	for (int i = 0; i < ProcessCount; ++i)
	{
		Request[i] = new int[SourceCount];
		for (int j = 0; j < SourceCount; ++j)
			Request[i][j] = 0;
	}

	Available = new int[SourceCount];
	for (int i = 0; i < SourceCount; ++i)
		Available[i] = 0;

	Max = new int*[ProcessCount];
	for (int i = 0; i < ProcessCount; ++i)
	{
		Max[i] = new int[SourceCount];
		for (int j = 0; j < SourceCount; ++j)
			Max[i][j] = 0;
	}

	Allocation = new int*[ProcessCount];
	for (int i = 0; i < ProcessCount; ++i)
	{
		Allocation[i] = new int[SourceCount];
		for (int j = 0; j < SourceCount; ++j)
			Allocation[i][j] = 0;
	}

	Need = new int*[ProcessCount];
	for (int i = 0; i < ProcessCount; ++i)
	{
		Need[i] = new int[SourceCount];
		for (int j = 0; j < SourceCount; ++j)
			Need[i][j] = 0;
	}

	//初始化各类资源
	std::cout << "请输入Available:\n";
	for (int i = 0; i < SourceCount; ++i)
		std::cin >> Available[i];

	std::cout << "请输入Max:\n";
	for (int i = 0; i < ProcessCount; ++i)
		for (int j = 0; j < SourceCount; ++j)
			std::cin >> Max[i][j];

	std::cout << "请输入Allocation:\n";
	for (int i = 0; i < ProcessCount; ++i)
		for (int j = 0; j < SourceCount; ++j)
		{
			std::cin >> Allocation[i][j];
			Need[i][j] = Max[i][j] - Allocation[i][j];	//求出Need
		}

	//初始化请求向量
	std::cout << "请输入请求向量:\n";
	for (int i = 0; i < ProcessCount; ++i)
	{
		std::cout << "进程" << i << ": ";
		for (int j = 0; j < SourceCount; ++j)
		{
			std::cin >> Request[i][j];
			if (Request[i][j] > Need[i][j])
			{
				std::cout << "Request > Need, 出错, 重新输入" << std::endl;
				--j;
				continue;
			}
		}
	}
}

//银行家算法
void bank()
{
	//标识请求是否完成
	bool *finish = new bool[ProcessCount];
	for (int i = 0; i < ProcessCount; ++i)
		finish[i] = false;

	for (int i = 0; i < ProcessCount; ++i)
	{
		if (finish[i])
			continue;

		for (int j = 0; j < SourceCount; ++j)
		{
			if (Request[i][j] > Available[j])
			{
				finish[i] = false;
				break;
			}
			finish[i] = true;
		}

		//可以进行尝试分配
		if (finish[i])
		{
			for (int j = 0; j < SourceCount; ++j)
			{
				Available[j] -= Request[i][j];
				Allocation[i][j] += Request[i][j];
				Need[i][j] -= Request[i][j];
			}

			//执行安全性算法
			if (!safe())		//如果不安全
			{
				finish[i] = false;
				//恢复资源
				for (int j = 0; j < SourceCount; ++j)
				{
					Available[j] += Request[i][j];
					Allocation[i][j] -= Request[i][j];
					Need[i][j] += Request[i][j];
				}
			}
			else //如果系统处于安全状态
			{
				int j;
				for (j = 0; j < SourceCount; ++j)
					if (Need[i][j])
						break;
				if (j == SourceCount)	//此请求使得进程运行完毕,释放资源
				{
					for (j = 0; j < SourceCount; ++j)
					{
						Available[j] += Allocation[i][j];
						Allocation[i][j] = 0;
					}
				}
				//记录进安全序列
				recorder[num++] = i;
				i = -1;	 //从头扫描请求
			}
		}
	}
	delete[] Available;
	delete[] Max;
	delete[] Allocation;
	delete[] Need;
	delete[] Request;
	delete[] finish;
}

//安全性算法
bool safe()
{
	//初始化work向量
	int *work;
	work = new int[SourceCount];
	for (int i = 0; i < SourceCount; ++i)
		work[i] = Available[i];

	//初始化finish向量
	bool *finish = new bool[ProcessCount];
	for (int i = 0; i < ProcessCount; ++i)
		finish[i] = false;

	//检查是否满足安全性算法
	for (int i = 0; i < ProcessCount; ++i)
	{
		if (!finish[i])
		{
			int j;
			for (j = 0; j < SourceCount; ++j)
			{
				if (Need[i][j] > work[j])
					break;
			}
			if (j == SourceCount)
			{
				finish[i] = true;
				for (j = 0; j < SourceCount; ++j)
					work[j] += Allocation[i][j];
				i = -1;	//重新扫描一遍
			}
		}
	}

	//如果全部满足finish = true,则为安全状态,否则为不安全状态
	for (int i = 0; i < ProcessCount; ++i)
		if (!finish[i])
		{
			delete[] work;
			delete[] finish;
			return false;
		}
	delete[] work;
	delete[] finish;
	return true;
}
    原文作者:银行家问题
    原文地址: https://blog.csdn.net/acm_yuuji/article/details/50380719
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞