广州大学操作系统实验 2020版 银行家算法

银行家算法

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

1.所需数据结构:
  1. Available[j]=k: 可用资源数组,现有资源j的数目为k。
  2. Max[i,j]=k: 最大需求量矩阵,进程i对资源j的最大需求数目为k。
  3. Allocation[i,j]=k: 分配资源矩阵,进程i当前已分得的资源j的数目为k。
  4. Need[i,j]=k: 需求矩阵,进程i尚需分配的资源j的数目k。
2.安全性算法:

两个向量:work和finish:

  1. work:表示系统可提供进程继续运行所需的各类资源数目(即在分配过程中,系统的可用资源数)。
    初始化:work=Available;
  2. finish:表示系统是否有足够的资源分配给进程i,使之运行完成。
    初始化:finish[i]=false;
    当有足够资源分配给进程时:finish[i]=true;
    广州大学操作系统实验 2020版 银行家算法_第1张图片
3.实验要求
  1. 画出银行家算法流程图;
  2. 对算法所用的数据结构进行说明;
  3. 测试数据随机产生。不可手工输入;
  4. 编写程序并调试;
  5. 多次测试程序,截屏输出实验结果;
  6. 根据实验结果与理论课讲述的原理进行实验分析。
4.流程图

广州大学操作系统实验 2020版 银行家算法_第2张图片

5.心心念念的代码
#include
#include
#include
using namespace std;
#define resourceNum 3
#define processNum  5
int available[resourceNum];
int maxRequest[processNum][resourceNum];
int allocation[processNum][resourceNum];
int need[processNum][resourceNum];
bool Finish[processNum];
int safeSeries[processNum] = { 0,0,0,0,0 };
int request[resourceNum];
int num;
void initData()
{
	srand(int(time(NULL)));
	for (int i = 0; i < resourceNum; i++)
	{
		available[i] = rand() % (5);//生成0-4的随机整数
	}
	for (int i = 0; i < processNum; i++)
	{
		for (int j = 0; j < resourceNum; j++)
		{
			int temp = rand() % (8 - 3);//生成0-4随机整数
			allocation[i][j] = temp;
			maxRequest[i][j] = rand() % (4) + temp;//这里确保了maxRequest[i][j]>=allocation[i][j].数据合理
			need[i][j] = maxRequest[i][j] - allocation[i][j];
		}
	}
}
void showInfo() {
	cout << "**********************************" << endl;
	cout << "当前系统各类可用资源:";
	for (int i = 0; i < resourceNum; i++)
	{
		cout << available[i] << " ";
	}
	cout << endl;
	cout << "当前系统资源情况" << endl;
	cout << "PID" << '\t' << "Max" << '\t' << "Allocation" << '\t' << "Need" << endl;
	for (int i = 0; i < processNum; i++)
	{
		cout << "P" << i << '\t';
		for (int j = 0; j < resourceNum; j++)
		{
			cout << maxRequest[i][j] << " ";
		}
		cout << '\t';
		for (int j = 0; j < resourceNum; j++)
		{
			cout << allocation[i][j] << " ";
		}
		cout << '\t'<<'\t';
		for (int j = 0; j < resourceNum; j++)
		{
			cout << need[i][j] << " ";
		}
		cout << endl;
	}
}
void safeInfo(int *work,int i)
{
	cout <<"P"<< i << '\t';
	for (int j = 0; j < resourceNum; j++)
	{
		cout << work[j] << " ";
	}
	cout << '\t'<<'\t';
	for (int j = 0; j < resourceNum; j++)
	{
		cout << allocation[i][j] << " ";
	}
	cout << '\t' << '\t';
	for (int j = 0; j < resourceNum; j++)
	{
		cout << need[i][j] << " ";
	}
	cout << '\t' << '\t';
	for (int j = 0; j < resourceNum; j++)
	{
		cout << allocation[i][j] + work[j] << " ";
	}
	cout << endl;
}
bool isAllZero(int index)//判断一个进程中是否所有资源都为0
{
	num = 0;//全局变量
	for (int i = 0; i < resourceNum; i++)
	{
		if (need[index][i] == 0)
		{
			num++;
		}
	}
	if(num==resourceNum)
	{
		return true;
	}
	else {
		return false;
	}
}
bool isSafe()
{
	int safeIndex = 0;
	int allFinish = 0;
	int work[resourceNum] = { 0 };
	int index = 0;
	int temp = 0;
	int pNum = 0;
	for (int i = 0; i < resourceNum; i++)//预分配
	{
		work[i] = available[i];
	}
	for (int i = 0; i < processNum; i++)
	{
		bool result = isAllZero(i);
		if (result) {
			Finish[i] = true;
			allFinish++;
		}
		else {
			Finish[i] = false;
		}
	}
	while (allFinish != processNum)//当所有进程都被分配完才结束循环
	{
		num = 0;
		for (int i=0; i < resourceNum; i++)
		{
			if (need[index][i] <= work[i] && Finish[index] == false)
			{
				num++;
			}
		}
		if (num == resourceNum)//说明该进程满足剩余的资源分配条件,对其进行预分配
		{
			for (int i = 0; i < resourceNum; i++)
			{
				work[i] = work[i] + allocation[index][i];//预回收资源
			}
			allFinish++;
			safeInfo(work, index);
			safeSeries[safeIndex] = index;
			safeIndex++;
			Finish[index] = true;
		}
		index++;
		if (index >= processNum)
		{
			index = index % processNum;
			if (temp == allFinish)
			{
				break;
			}
			temp = allFinish;
		}
		pNum = allFinish;
	}
	for (int i = 0; i < processNum; i++)
	{
		if (Finish[i] == false)
		{
			cout << "当前系统不安全!" << endl;
			return false;
		}
	}
	cout << "当前系统安全!" << endl;
	cout << "安全系列为:";
	for (int i = 0; i < processNum; i++)
	{
		bool result = isAllZero(i);
		if (result)
		{
			pNum--;
		}
	}
	for (int i = 0; i < pNum; i++)
	{
		cout << safeSeries[i] << " ";
	}
	cout << endl;
	return true;
}
int main()
{
	initData();
	showInfo();
	int currentProcess = 0;//要处理的进程
	cout << "系统安全情况分析" << endl;
	cout << "PID" << '\t' << "Work" << '\t'<<'\t' << "Allocation" << '\t' << "Need" <<'\t'  <<"Work+Allocation"<<endl;
	bool isStart = isSafe();
	while (isStart)
	{
		cout << "***********************************" << endl;
		cout << "请输入要分配的进程:";
		cin >> currentProcess;
		cout << endl;
		for (int i = 0; i < resourceNum; i++)
		{
			cout << "请输入分配给P" << currentProcess << "第" << i + 1 << "类资源:";
			cin >> request[i];
		}
		num = 0;
		for (int i = 0; i < resourceNum; i++)
		{
			if (request[i] <= need[currentProcess][i] && request[i] <= available[i])
			{
				num++;
			}
			else {
				cout << "请求分配的资源不合理" << endl;
				break;
			}
		}
		if (num == resourceNum)//所请求数据都合理
		{
			num = 0;
			for (int i = 0; i < resourceNum; i++)
			{
				available[i] -=request[i];
				allocation[currentProcess][i] += request[i];
				need[currentProcess][i] -= request[i];
				if (need[currentProcess][i]==0)
				{
					num++;
				}
			}
			if (num == resourceNum)//说明某顾客完成资源分配,回收资源
			{
				for (int i = 0; i < resourceNum; i++)
				{
					available[i] += allocation[currentProcess][i];
				}
				cout << "本次分配进程" << currentProcess << "完成,该进程所占用资源回收!" << endl;
			}
			else {
				cout << "本次分配进程" << currentProcess << "仍未完成该进程" << endl;
			}
			showInfo();
			cout << "系统安全情况分析" << endl;
			cout << "PID" << '\t' << "Work" << '\t' << "Allocation" << '\t' << "Need" << '\t' << "      " << "Work+Allocation" << endl;
			if (!isSafe())//不安全,将预分配资源恢复
			{
				for (int i = 0; i < resourceNum; i++)
				{
					available[i] += request[i];
					allocation[currentProcess][i] -= request[i];
					need[currentProcess][i] += request[i];
				}
				cout << "资源不足,等待分配资源" << endl;
			}
		}
	}
}

广州大学操作系统实验 2020版 银行家算法_第3张图片
广州大学操作系统实验 2020版 银行家算法_第4张图片
广州大学操作系统实验 2020版 银行家算法_第5张图片

6.代码不足之处
  1. 这里的难点之一就是题目的第3个要求,用随机数初始化数据。生成随机数不是很简单吗?确实。但是要符合题意的就难了。你得保证任意一个顾客随机生成的已分配资源Allocation[i][j]必须小于等于最大需求资源Max[i][j],你不能顾客贷款10万,就直接初始化给顾客20万了吧。其次,生成随机数具有很多不确定性。因此,运行上面代码可能看到很多是该系统不安全的结果,暂时还没想出生成哪个范围的随机数更适合实验。
  2. 哈哈,控制台打印的结果太丑了吧,参吃不起。
  3. 若有下图结果,这是正常的,因为随机来的数据,难以控制。

广州大学操作系统实验 2020版 银行家算法_第6张图片

若有帮助到您,请给个赞噢!

你可能感兴趣的:(操作系统,操作系统,算法)