c++模拟银行家算法

在复习408时,使用代码模拟能够加深对知识点的理解

1.银行家算法介绍

银行家算法是迪杰斯特拉发明的死锁避免的算法。找到合理的资源分配序列保证各进程的正常推进是银行家算法的核心。

2.自定义类以及成员变量和成员函数说明

进程类

//进程类
class Process;
//资源最大需求量
Process::vector<int>MaxNeed;
//已经分配资源数量
Process::vector<int>allocated;
//还需要资源数量
Process::vector<int>remainNeed;

银行家算法类

//银行家算法类
class BankerAlgorithm;
//进程指针数组
BankerAlgorithm::vector<Process*>Processes;
//资源数数组
BankerAlgorithm::vector<int>Resource;
//加载进程
BankerAlgorithm::void loadProcess(int& kind);
//判断该进程是否可以分配
BankerAlgorithm::bool match(int index);
//归还已有资源
BankerAlgorithm::void refundResource(int index);
//寻找安全序列
BankerAlgorithm::void FindSafeSequence()

3.程序执行过程说明

3.1按照下标范围遍历进程,比较进程所需资源和剩余资源数量

如果进程所需资源数量都小于等于剩余资源数,返回true,否则false

bool match(int index) {
	for (int i = 0; i < Resource.size(); ++i) {
		//比较每种资源是否满足数量
		if (Processes[index]->remainNeed[i] > Resource[i]) {
			return false;
		}
	}
	return true;
}
3.2归还资源

如果"3.1"返回了true,说明可以分配,接下来将资源全部退回给操作系统【因为只是模拟分配,分配完了立刻使用归还】

void refundResource(int index) {
	for (int i = 0; i < Resource.size(); ++i) {
		Resource[i] += Processes[index]->allocated[i];
	}
}

全部代码

#include<iostream>
#include<vector>
using namespace std;
class Process {
public:
	int ID;//进程ID
	vector<int>MaxNeed;//最大需求
	vector<int>allocated;//已分配资源
	vector<int>remainNeed;//还要资源
	Process(int& Id,int kind) {//进程名 资源种类数量
		ID = Id;
		MaxNeed.resize(kind);
		allocated.resize(kind);
		remainNeed.resize(kind);
		cout << "请输入每种资源最大需求量:";
		for (int i = 0; i < kind; ++i) {
			cin >> MaxNeed[i];
		}
		cout << "请输入每种资源已分配数量:";
		for (int i = 0; i < kind; ++i) {
			cin >> allocated[i];
		}
		cout << "自动计算还需资源数量!"<<endl;
		for (int i = 0; i < kind; ++i) {
			remainNeed[i] = MaxNeed[i] - allocated[i];
		}
	}
};
class BankerAlgorithm {
public:
	vector<Process*>Processes;//进程
	vector<int>Resource;//各类资源当前剩余量
	BankerAlgorithm() {
		cout << "请输入资源种类数量:";
		int kind;
		cin >> kind;
		this->Resource.resize(kind);
		cout << "请输入各种资源当前空闲的数量:";
		for (int i = 0; i < kind; ++i) {
			cin >> Resource[i];
		}
		cout << "加载进程" << endl;
		loadProcess(kind);
		FindSafeSequence();
	}
	void loadProcess(int& kind) {//加载进程
		int cnt;
		cout << "输入进程数:";
		cin >> cnt;
		Processes.resize(cnt);
		for (int i = 0; i < cnt; ++i) {
			printf("请输入第%d个进程信息\n", i);
			Processes[i] = new Process(i, kind);
		}
	}
	//判断是否可以将资源分配给当前下标的进程
	bool match(int index) {
		for (int i = 0; i < Resource.size(); ++i) {
			//比较每种资源是否满足数量
			if (Processes[index]->remainNeed[i] > Resource[i]) {
				return false;
			}
		}
		return true;
	}
	//归还资源
	void refundResource(int index) {
		for (int i = 0; i < Resource.size(); ++i) {
			Resource[i] += Processes[index]->allocated[i];
		}
	}
	//寻找安全序列
	void FindSafeSequence() {
		//寻找范围变化,如果找到一个可分配进程,就会与最后一个进程交换位置
		// 缩小下一次查找范围【已经分配完的进程不需要再分配了】
		bool flag;
		for (int i = Processes.size() - 1; i >= 0; --i) {
			flag = false;//标记是否找到当前不会造成死锁的进程
			for (int j = 0; j <= i; ++j) {
				if (match(j)) {
					//如果满足银行家算法,说明可以归还资源
					refundResource(j);
					flag = true;
					//将进程放到最后【表示已经用完资源并且归还】
					swap(Processes[j], Processes[i]);
					break;
				}
			}
			//没有可以分配资源的进程【说明已经进入死锁状态】
			if (!flag) {
				break;
			}
		}
		if (flag) {
			cout << "找到一个安全序列:";
			printf("p%d", Processes[Processes.size() - 1]->ID);
			for (int i = Processes.size() - 2; i >= 0; --i) {
				printf("->p%d", Processes[i]->ID);
			}
		}
		else {
			cout << "不存在安全序列!" << endl;
		}
	}
};
int main() {
	BankerAlgorithm bank;
	cout << endl;
}

来自王道书的例子
在这里插入图片描述

在这里插入图片描述
以下是输入数据【可复制】

3
3 3 2
5
7 5 3
0 1 0

3 2 2
2 0 0

9 0 2
3 0 2

2 2 2
2 1 1

4 3 3
0 0 2
  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Mystic Musings

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

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

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

打赏作者

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

抵扣说明:

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

余额充值