银行家算法:避免死锁的著名算法,以银行借贷系统为基础,保障系统安全运行

银行家算法介绍概念

银行算法(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发出资源请求后,系统按下述步骤进行检査:

如果 Requesti[j] ≤ Need[i,j]便转向步骤2 否则认为出错因为它所需要的资源数已超过它所事先声明需要的最大值。如果 Requesti[j] ≤ Available[j],便转向步骤3;否则,表示尚无足够资源,Pi须等待。系统试探着把资源分配给进程Pi,并修改下面数据结构中的数值Available[j] = Available[j] – Requesti[j];Allocation[i,j] = Allocation[i,j] + Requesti[j];Need[i,j] = Need[i,j] – Requesti[j];系统执行安全性算法检查此次资源分配后系统是否处于安全状态。若安全,才正式将资源分配给进程Pi,以完成本次分配;否则,将本次的试探分配作废,恢复原来的资源分配状态,让进程Pi等待安全性算法

系统所执行的安全性算法可描述如下:

设置两个向量:从进程集合中找到一个能满足下述条件的进程① Finish[i] = false;② Need[i,j] ≤ Work[j];若找到,执行步骤3,否则,执行步骤4。当进程Pi获得资源后,可顺利执行,直至完成,并释放出分配给它的资源,故应执行:Work[j] = Work[j] + Allocation[i,j];Finish[i] = true;go to step 2;如果所有进程的 Finish[i] =true都满足,则表示系统处于安全状态;否则,系统处于不安全状态。代码

C++的银行家算法的具体实现代码(By Titan)

代码语言:javascript

复制

#include
#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> Max[i][j];
        }
    }
}
void inputAllocationMartix() {
    cout << "请输入Allocation矩阵的数据:" << endl;
    for(int i=0; i<totalProcess; i++) {
        for(int j=0; j> Allocation[i][j];
        }
    }
}
void inputAvailable() {
    cout << "请输入Available资源向量" << endl;
    for(int i=0; i> 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" <<  "tt" << "Max" <<  "tt" << "Allocation" <<  "tt" << "Need" << endl;
    for(int i=0; i<totalProcess; i++) {
        cout << i <<  "ttt";
        for(int j=0; j<totalResource; j++) {
            cout << Max[i][j] << " ";
        }
        cout <<  "ttt";
        for(int j=0; j<totalResource; j++) {
            cout << Allocation[i][j] << " ";
        }
        cout <<  "ttt";
        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 work[j]) {
                        flag = false;
                        break;
                    }
                }
                if(flag) {
                    finish[i] = true;
                    safeSeq[count++] = i;
                    for(int j=0; j0);
    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:" <> requestPid;
    cout << "请输入请求向量Request:" << endl;
    for(int i=0; i> request[i];
    }
    for(int i=0; i Need[requestPid][i]) {
            cout << "请求资源数大于需要数量,分配失败" < 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 << "请输入进程数量:" <> totalProcess;
    cout << "请输入资源种类数量:" <> totalResource;
    inputMaxMartix();
    inputAllocationMartix();
    inputAvailable();
    calculateNeed();
    print();
    check();
    while(true){
        char signal;
        handleRequest();
        cout << "输入Y继续,输入N退出" <>  signal;
        if(signal == 'N'){
            return 0;
        }
    }
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注