银行家算法的实现

吐槽

我们学校软件工程对OS教学要求真的低,我们的课程设计竟然是计科的普通实验内容

认真写注释,真的好累。(但是代码不写注释都是在耍流氓)


一、实验目的
1、加深理解银行家算法及相关概念。
2、掌握进程申请资源时的安全性检查算法。
3、能看懂资源分配表(教材p122图3-5)。

二、实验原理
1、银行家算法原为银行系统设计,以确保银行在发放现金贷款时,不会发生不能满足所有客户需求的情况。银行家算法可以帮助操作系统避免死锁(将客户比作进程,贷款单位比作资源,银行家比作操作系统)。
2、为实现银行家算法,每个进程必须事先声明自己需要的每种资源类型的最大数目。当进程请求资源时,系统必须确保该进程所拥有的资源数不超过它事先声明最大资源数,同时确保资源请求量不超过当前可用资源量。若两项均满足则执行安全性检查算法。
3、安全性检查算法用于检查系统进行资源分配后是否安全,若安全,系统才可执行此次分配,否则不执行此次分配。
4、安全性检查算法:在系统试分配资源后,算法从现有进程列表中寻找出一个可执行进程,回收该进程占用的资源,并寻找下一个可执行进程。若某种执行顺序能够使得所有进程能依次执行,则产生一个安全执行序列,并允许此次资源分配。若进程无法全部执行(无法找到一个安全序列),则本次资源分配将导致系统进入不安全状态,故本次资源请求失败。

不多说直接上代码

//mybanker.h
#ifndef MYBANKER_H
#define MYBANKER_H
#include<vector>
#include<iostream>
using namespace std;
class MyBanker
{
public:
	MyBanker(int rCount, int pCount, vector<vector<int > >maxNeed, vector<vector<int > >allocation, vector<int > available);
	~MyBanker();
	bool isSafe();
	int banker(vector<int> request);
	vector<vector<int > > generateRequests(int n);

private:
	int m_vResourceOfTypesCount;  //资源种类数
	int m_vProcessCount;          //进程数量
	vector<vector<int > > m_vMax;				  //最大需求矩阵
	vector<vector<int > > m_vAllocation;			  //分配矩阵
	vector<vector<int > > m_vNeed;                 //需求矩阵 
	vector<int > m_vAvailable;					//可利用向量				

};


//mybanker.cpp
#include"mybanker.h"

/********************************************************************************************
* 函数名:MyBanker
* 输入参数:rCount:资源数 pCount:进程数 maxNeed:最大需求矩阵 allocation:分配矩阵 available:可利用向量
* 返回: 无
* 函数作用:构造函数
* 作者:RedHaohao
*********************************************************************************************/
MyBanker::MyBanker(int rCount, int pCount, vector<vector<int > >maxNeed, vector<vector<int > >allocation, vector<int > available)
{
	m_vResourceOfTypesCount = rCount;
	m_vProcessCount = pCount;
	m_vAllocation = allocation;
	m_vMax = maxNeed;
	m_vAvailable = available;

	vector<int >temp;
	for (int i = 0; i < pCount; i++)
	{
		for (int j = 0; j < rCount; j++)
		{
			//需求=最大需求-已分配
			temp.push_back(maxNeed[i][j] - allocation[i][j]);
		}
		m_vNeed.push_back(temp);
		temp.clear();
	}
	for (int i = 0; i < pCount; i++)
	{
		for (int j = 0; j < rCount; j++)
		{
			//可用=初始可用-已分配
			m_vAvailable[j] -= m_vAllocation[i][j];
		}
	}
}

MyBanker::~MyBanker()
{
	
}
/********************************************************************************************
* 函数名:banker
* 输入参数:vector<int > request:请求向量  request[0]为进程号 其他为请求资源值
* 返回: 1:请求可以满足 2:不能产生一个安全的序列 3:请求资源大于现在可利用的 4:不要这么多资源就可以完成任务
* 函数作用:银行家算法主体部分
* 作者:RedHaohao
* 需要改进:通过返回值来输出对应提示消息
*********************************************************************************************/
int MyBanker::banker(vector<int>  request)
{
	bool requestSmallerNeed=true;
	bool requestSmallerAvailable=true;
	int processID = request[0];
	for (int i = 1; i < request.size(); i++)
	{
		
		
		//如果请求的大于需要的
		if (request[i] > m_vNeed[processID][i-1])
		{
			requestSmallerNeed = false; //请求失败
			cout << "你其实不需要这么多就可以完成任务哦" << endl;
			return 4;//不需要这么多
		}
		//如果请求的大于可利用的
		if (request[i] > m_vAvailable[i - 1])
		{
			requestSmallerAvailable = false; //请求失败
			cout << "我这里没有这么多资源啊" << endl;
			return 3;//没有这么多
		}

	}
	if (requestSmallerNeed&&requestSmallerAvailable)
	{
		for (int i = 1; i < request.size(); i++)
		{
			//可利用的=原来可利用的-要求的
			//已分配的=原来分配的+请求的
			//需要的=原来需要的-请求的
			m_vAvailable[i - 1] -= request[i];
			m_vAllocation[processID][i - 1] += request[i];
			m_vNeed[processID][i - 1] -= request[i];

		}
		if (isSafe())
		{
			//为符合题意多次测试,真正的应该不做还原操作。
			for (int i = 1; i < request.size(); i++)
			{
				
				m_vAvailable[i - 1] += request[i];
				m_vAllocation[processID][i - 1] -= request[i];
				m_vNeed[processID][i - 1] += request[i];

			}
			cout << "大兄弟可以的" << endl;
			return 1;
		}
		else
		{
			for (int i = 1; i < request.size(); i++)
			{
				
				m_vAvailable[i - 1] += request[i];
				m_vAllocation[processID][i - 1] -= request[i];
				m_vNeed[processID][i - 1] += request[i];

			}
			cout << "不,这不安全" << endl;
			return 2;
		}
	}


}
/********************************************************************************************
* 函数名:banker
* 输入参数:
* 返回: true: 该请求是安全的  false:该请求无法产生一个可执行的进程序列
* 函数作用:安全检查,检验是否可以产生一个有序队列
* 作者:RedHaohao
* 需要改进:
*********************************************************************************************/
bool MyBanker::isSafe()
{
	vector<int > work = m_vAvailable;
	vector<int > finish;
	for (int i = 0; i < m_vProcessCount; i++)
	{
		finish.push_back(0);//0表示未完成
	}
	bool enough;
	bool existZero = true;
	while (existZero)
	{
		existZero = false;
		for (int i = 0; i < m_vProcessCount; i++)
		{
			enough = true;

			if (finish[i] == 0)
			{
				
				for (int j = 0; j < m_vResourceOfTypesCount; j++)
				{
					if (m_vNeed[i][j] > work[j])
					{
						enough = false;
						break;
					}
				}
				if (enough)
				{
					existZero = true;
					for (int k = 0; k < m_vResourceOfTypesCount; k++)
					{
						work[k] += m_vAllocation[i][k];

					}
					finish[i] = 1;
					cout << "序列 " << i;
				}
			}
		}
	}
	for (int i = 0; i < m_vProcessCount; i++)
	{
		if (finish[i] == 0)
			return false;
	}
	return true;
}
/********************************************************************************************
* 函数名:generateRequests
* 输入参数:n:测试次数
* 返回: 测试请求的二维向量
* 函数作用:生成测试的vector<vector <int >>
* 作者:RedHaohao
* 需要改进:
*********************************************************************************************/
vector<vector<int > > MyBanker::generateRequests(int n)
{
	int num;
	vector<vector<int > > requests;
	vector<int > temp;

	for (int i = 0; i < n;i++)
	{ 
		cout << "请输入测试样例" << endl;
		cin >> num;
		temp.push_back(num);
		
		for (int j = 1; j <= m_vResourceOfTypesCount; j++)
		{
			
			cin >> num;
			temp.push_back(num);
		}
		requests.push_back(temp);
		temp.clear();
	} 
	return  requests;

}
#endif

//main
#include"mybanker.h"

int main()
{
	int resourceOfTypesCount;
	int processCount;

	cout << "输入进程数" << endl;
	cin >> processCount;
	cout << "输入资源种类数" << endl;
	cin >> resourceOfTypesCount;

	vector<vector<int >> maxNeed ;
	vector<vector<int >> allocation ;
	vector<int > available;

	cout << "输入系统中各资源总数量" << endl;
	
	int temp;
	for (int i = 0; i < resourceOfTypesCount; i++)
	{
		cin >> temp;
		available.push_back(temp);
	}

	cout << "输入进程需要各类资源总数量" << endl;
	vector<int > temp2;
	for (int i = 0; i < processCount; i++)
	{
		for (int j = 0; j < resourceOfTypesCount; j++)
		{
			cin >> temp;
			temp2.push_back(temp);
		}
		maxNeed.push_back(temp2);
		temp2.clear();
	}

	cout << "输入进程已经分配的资源数量" << endl;
	for (int i = 0; i < processCount; i++)
	{
		for (int j = 0; j < resourceOfTypesCount; j++)
		{
			cin >> temp;
			temp2.push_back(temp);
		}
		allocation.push_back(temp2);
		temp2.clear();
	}


	int n;

	MyBanker me(resourceOfTypesCount, processCount, maxNeed, allocation, available);
	cout << "请输入测试次数" << endl;
	cin >> n;
	vector<vector<int> > requests=me.generateRequests(n);
	for (int i = 0; i < n; i++)
	{
		me.banker(requests[i]);
	}
	system("pause");
	return 0;
}

R向量即系统总资源数
C矩阵即最大需求矩阵
A矩阵即已分配矩阵
在这里插入图片描述

测试用例
输入
5 3
10 5 7
7 5 3
3 2 2
9 0 2
2 2 2
4 3 3
0 1 0
2 0 0
3 0 2
2 1 1
0 0 2
6
1 1 0 2
1 1 2 2
4 3 3 0
0 3 5 1
2 5 0 0
2 5 1 0
输出如图
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值