在复习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;//进程IDvector<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 03 2 2
2 0 09 0 2
3 0 22 2 2
2 1 14 3 3
0 0 2