银行家算法(Banker’s Algorithm)是一个避免死锁(Deadlock)的著名算法,是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的一种避免死锁产生的算法。它以银行借贷系统的分配策略为基础,判断并保证系统的安全运行。
在银行中,客户申请贷款的数量是有限的,每个客户在第一次申请贷款时要声明完成该项目所需的最大资金量,在满足所有贷款要求时,客户应及时归还。银行家在客户申请的贷款数量不超过自己拥有的最大值时,都应尽量满足客户的需要。在这样的描述中,银行家就好比操作系统,资金就是资源,客户就相当于要申请资源的进程。
银行家算法是一种最有代表性的避免死锁的算法。在避免死锁方法中允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次分配资源的安全性,若分配不会导致系统进入不安全状态,则分配,否则等待。为实现银行家算法,系统必须设置若干数据结构。
为了实现银行家算法,在系统中必须设置这样四个数据结构,分别用来描述系统中可利用的资源、所有进程对资源的最大需求、系统中的资源分配,以及所有进程还需要多少资源的情况。
上述三个矩阵间存在下述关系: Need[i,j] = Max[i,j] - Allocation[i, j]
设 Request;是进程Pi的请求向量,如果 Requesti[j] = K,表示进程Pi需要K个Rj类型的资源。当Pi发出资源请求后,系统按下述步骤进行检査:
系统所执行的安全性算法可描述如下:
C++的银行家算法的具体实现代码(By Titan)
#include<iostream>
#define MAX 100
using namespace std;
int totalResource,totalProcess;
int Max[MAX][MAX]; // 最大需求矩阵max
int Allocation[MAX][MAX]; // 分配矩阵
int Need[MAX][MAX]; // 最多还需要资源矩阵
int Available[MAX]; // 可用资源向量
void inputMaxMartix() {
cout << "请输入Max矩阵的数据:" << endl;
for(int i=0; i<totalProcess; i++) {
for(int j=0; j<totalResource; j++) {
cin >> Max[i][j];
}
}
}
void inputAllocationMartix() {
cout << "请输入Allocation矩阵的数据:" << endl;
for(int i=0; i<totalProcess; i++) {
for(int j=0; j<totalResource; j++) {
cin >> Allocation[i][j];
}
}
}
void inputAvailable() {
cout << "请输入Available资源向量" << endl;
for(int i=0; i<totalResource; i++) {
cin >> Available[i];
}
}
// 通过Max矩阵和Allocation矩阵的数据来计算Need矩阵
void calculateNeed() {
for(int i=0; i<totalProcess; i++) {
for(int j=0; j<totalResource; j++) {
Need[i][j]=Max[i][j]-Allocation[i][j];
}
}
}
// 输出当前数据
void print() {
cout << "当前资源分配情况:" << endl;
cout << "进程ID" << "\t\t" << "Max" << "\t\t" << "Allocation" << "\t\t" << "Need" << endl;
for(int i=0; i<totalProcess; i++) {
cout << i << "\t\t\t";
for(int j=0; j<totalResource; j++) {
cout << Max[i][j] << " ";
}
cout << "\t\t\t";
for(int j=0; j<totalResource; j++) {
cout << Allocation[i][j] << " ";
}
cout << "\t\t\t";
for(int j=0; j<totalResource; j++) {
cout << Need[i][j] << " ";
}
cout << endl;
}
cout << "各类资源可用数量:" << endl;
for(int i=0; i<totalResource; i++) {
cout << Available[i] << " ";
}
cout << endl;
}
//安全性检查函数
bool check() {
int safeSeq[totalProcess];
int work[totalResource];
int count = 0; // 安全序列Cursor;
bool finish[totalProcess];
for(int i=0; i<totalProcess; i++) {
safeSeq[i] = 0;
finish[i] = false;
}
for(int i=0; i<totalResource; i++) {
work[i] = Available[i];
}
int unfinished = totalProcess;
bool flag;
do {
for(int i=0; i<totalProcess; i++) {
if(finish[i] == false) {
flag = true;
for(int j=0; j<totalResource; j++) {
if(Need[i][j] > work[j]) {
flag = false;
break;
}
}
if(flag) {
finish[i] = true;
safeSeq[count++] = i;
for(int j=0; j<totalResource; j++) {
work[j] += Allocation[i][j];
}
}
}
}
unfinished--;
} while(unfinished>0);
flag = true;
// 判断是否所有进程都完成
for(int i=0; i<totalProcess; i++) {
if(finish[i]==false) {
flag=false;
break;
}
}
// 判断是否安全
if(flag==false) {
cout << "系统处于不安全状态!" << endl;
} else {
cout << "系统当前为安全状态,安全序列为:" << endl;
for(int i=0; i<totalProcess; i++) {
cout << safeSeq[i] << " ";
}
cout << endl;
}
return flag;
}
void handleRequest() {
int requestPid;
int request[totalResource];
int snapShotOfAvailable[totalResource];
int snapShotOfAllocation[totalResource];
int snapShotOfNeed[totalResource];
cout << "请输入请求资源的ID:" << endl;
cin >> requestPid;
cout << "请输入请求向量Request:" << endl;
for(int i=0; i<totalResource; i++) {
cin >> request[i];
}
for(int i=0; i<totalResource; i++) {
if(request[i] > Need[requestPid][i]) {
cout << "请求资源数大于需要数量,分配失败" <<endl;
return;
}
if(request[i] > Available[i]) {
cout << "可用资源不足,分配失败" << endl;
return;
}
}
// 尝试分配
for(int i=0; i<totalResource; i++) {
//保存快照
snapShotOfAvailable[i] = Available[i];
snapShotOfAllocation[i] = Allocation[requestPid][i];
snapShotOfNeed[i] = Need[requestPid][i];
// 进行尝试分配
Available[i] -= request[i];
Allocation[requestPid][i] += request[i];
Need[requestPid][i] -= request[i];
}
// 打印当前资源情况
print();
if(check() == false) { // 不安全,返回分配
// 恢复快照
for(int i=0; i<totalResource; i++) {
// 进行尝试分配
Available[i] = snapShotOfAvailable[i];
Allocation[requestPid][i] = snapShotOfAllocation[i];
Need[requestPid][i] -= snapShotOfNeed[i];
}
}
}
int main() {
cout << "请输入进程数量:" << endl;
cin >> totalProcess;
cout << "请输入资源种类数量:" << endl;
cin >> totalResource;
inputMaxMartix();
inputAllocationMartix();
inputAvailable();
calculateNeed();
print();
check();
while(true){
char signal;
handleRequest();
cout << "输入Y继续,输入N退出" << endl;
cin >> signal;
if(signal == 'N'){
return 0;
}
}
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。