银行家算法详解

一、概述

银行家算法(Banker's Algorithm)是一种经典的死锁避免算法,由计算机科学家Edsger Dijkstra在1965年提出。它主要用于操作系统中的资源分配,确保系统能够安全地进行资源分配和释放,避免因资源分配不当而导致的死锁。银行家算法的基本思想类似于银行在贷款时要保证其有足够的资金以应对所有客户的最大需求,以免因资金周转不灵而导致破产。

二、原理

银行家算法通过对系统当前状态和资源请求进行检查,来确保系统能够安全地分配资源。它通过模拟资源分配和检查系统是否进入安全状态来决定是否批准资源请求。

1. 系统模型

在银行家算法中,系统模型包括以下几个参数:

  • n:进程的数量。
  • m:资源类型的数量。
  • Available:长度为m的数组,表示系统当前可用的各类资源数目。
  • Maxn*m的矩阵,表示每个进程对各类资源的最大需求。
  • Allocationn*m的矩阵,表示每个进程当前已分配到的各类资源数目。
  • Needn*m的矩阵,表示每个进程尚需的各类资源数目。Need[i][j] = Max[i][j] - Allocation[i][j]
2. 安全性检查

银行家算法在进行资源分配前,会进行安全性检查,即在分配资源后,系统是否能够进入一个安全状态。安全状态是指系统中存在一个进程序列,使得每个进程能够在其最大需求得到满足后顺利执行完毕。

三、银行家算法步骤

银行家算法分为以下几个步骤:

  1. 初始化系统状态:设置初始的AvailableMaxAllocationNeed矩阵。
  2. 请求资源:当进程请求资源时,检查请求是否合法(即请求量不超过进程的最大需求和系统的可用资源)。
  3. 试探性分配:临时分配资源给进程,并更新系统状态。
  4. 安全性检查:调用安全性算法检查系统是否处于安全状态。如果安全,正式分配资源;否则,恢复原状态,拒绝请求。

四、银行家算法实例

假设有如下系统状态:

  • 资源类型:A、B、C
  • 进程数:5
  • 各资源的总数:A(10),B(5),C(7)

初始状态如下:

运行结果

当运行上述代码时,如果进程P1(即process_id = 1)请求资源[1, 0, 2],系统将检查该请求是否会导致系统进入不安全状态。如果安全,则批准请求并更新系统状态;否则,拒绝请求并恢复原始状态。

通过这种方式,银行家算法有效地避免了死锁问题,确保了系统的安全运行。

  • Available = [3, 3, 2]
  • Max矩阵:
  • [7, 5, 3],
     [3, 2, 2],
     [9, 0, 2],
     [2, 2, 2],
     [4, 3, 3]
  • Allocation矩阵:
  • [0, 1, 0],
  • [2, 0, 0],
  • [3, 0, 2],
  • [2, 1, 1],
  • [0, 0, 2]
  • Need矩阵(由Max - Allocation得出):
  • [7, 4, 3],
  • [1, 2, 2],
  • [6, 0, 0],
  • [0, 1, 1],
  • [4, 3, 1]
  • 假设进程P1请求资源[1, 0, 2]。以下是银行家算法的具体步骤:

  • 检查请求是否合法

    • 请求量不超过需求:Request <= Need,[1, 0, 2] <= [1, 2, 2]
    • 请求量不超过可用资源:Request <= Available,[1, 0, 2] <= [3, 3, 2]
  • 试探性分配

    • 更新AvailableAvailable = [3, 3, 2] - [1, 0, 2] = [2, 3, 0]
    • 更新AllocationAllocation[1] = [2, 0, 0] + [1, 0, 2] = [3, 0, 2]
    • 更新NeedNeed[1] = [1, 2, 2] - [1, 0, 2] = [0, 2, 0]
  • 安全性检查

    • 尝试找到一个安全序列,使得每个进程在获得资源后能够完成并释放资源。
    • 安全序列:P1 -> P3 -> P4 -> P0 -> P2
  • 正式分配资源:如果系统处于安全状态,则正式分配资源;否则,恢复原始状态,拒绝请求。

  • 五、银行家算法代码实现

    下面是C++实现银行家算法

  • #include <iostream>
    #include <vector>
    
    using namespace std;
    
    class BankersAlgorithm {
    private:
        int n;  // 进程数量
        int m;  // 资源类型数量
        vector<int> available;  // 当前可用的各类资源数目
        vector<vector<int>> max;  // 每个进程对各类资源的最大需求
        vector<vector<int>> allocation;  // 每个进程当前已分配到的各类资源数目
        vector<vector<int>> need;  // 每个进程尚需的各类资源数目
    
    public:
        BankersAlgorithm(int num_processes, int num_resources, vector<int> avail, vector<vector<int>> max_matrix, vector<vector<int>> alloc_matrix) {
            n = num_processes;
            m = num_resources;
            available = avail;
            max = max_matrix;
            allocation = alloc_matrix;
            need.resize(n, vector<int>(m));
            calculateNeed();
        }
    
        void calculateNeed() {
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    need[i][j] = max[i][j] - allocation[i][j];
                }
            }
        }
    
        bool isSafeState() {
            vector<int> work = available;
            vector<bool> finish(n, false);
            vector<int> safeSequence;
    
            while (safeSequence.size() < n) {
                bool found = false;
                for (int i = 0; i < n; i++) {
                    if (!finish[i]) {
                        bool canProceed = true;
                        for (int j = 0; j < m; j++) {
                            if (need[i][j] > work[j]) {
                                canProceed = false;
                                break;
                            }
                        }
                        if (canProceed) {
                            for (int k = 0; k < m; k++) {
                                work[k] += allocation[i][k];
                            }
                            safeSequence.push_back(i);
                            finish[i] = true;
                            found = true;
                        }
                    }
                }
                if (!found) {
                    return false;
                }
            }
            return true;
        }
    
        bool requestResources(int process_id, vector<int> request) {
            for (int i = 0; i < m; i++) {
                if (request[i] > need[process_id][i] || request[i] > available[i]) {
                    return false;  // 请求不合法
                }
            }
    
            // 试探性分配资源
            for (int i = 0; i < m; i++) {
                available[i] -= request[i];
                allocation[process_id][i] += request[i];
                need[process_id][i] -= request[i];
            }
    
            // 检查系统是否处于安全状态
            if (isSafeState()) {
                return true;  // 请求被批准
            } else {
                // 恢复原状态
                for (int i = 0; i < m; i++) {
                    available[i] += request[i];
                    allocation[process_id][i] -= request[i];
                    need[process_id][i] += request[i];
                }
                return false;  // 请求被拒绝
            }
        }
    };
    
    int main() {
        int n = 5;  // 进程数量
        int m = 3;  // 资源类型数量
    
        vector<int> available = {3, 3, 2};  // 当前可用的各类资源数目
    
        vector<vector<int>> max = {  // 每个进程对各类资源的最大需求
            {7, 5, 3},
            {3, 2, 2},
            {9, 0, 2},
            {2, 2, 2},
            {4, 3, 3}
        };
    
        vector<vector<int>> allocation = {  // 每个进程当前已分配到的各类资源数目
            {0, 1, 0},
            {2, 0, 0},
            {3, 0, 2},
            {2, 1, 1},
            {0, 0, 2}
        };
    
        BankersAlgorithm ba(n, m, available, max, allocation);
    
        int process_id = 1;  // 请求资源的进程ID
        vector<int> request = {1, 0, 2};  // 请求的资源向量
    
        if (ba.requestResources(process_id, request)) {
            cout << "资源请求被批准。系统处于安全状态。" << endl;
        } else {
            cout << "资源请求被拒绝。系统将进入不安全状态。" << endl;
        }
    
        return 0;
    }
    

    详细解释

  • 初始化系统状态

    • available:表示系统当前可用的各类资源数量。
    • max:每个进程对各类资源的最大需求。
    • allocation:每个进程当前已分配的各类资源数量。
    • need:每个进程尚需的各类资源数量,通过maxallocation矩阵计算得出。
  • 计算need矩阵

    • 使用calculateNeed函数,通过maxallocation矩阵计算出need矩阵。
  • 安全性检查

    • 使用isSafeState函数检查系统是否处于安全状态。
    • 初始化work数组为当前可用资源。
    • 使用finish数组记录每个进程是否完成。
    • 找到一个尚未完成且可以得到所有所需资源的进程,假设其完成并释放资源,更新work数组和finish数组。
    • 重复上述步骤,直到找到安全序列或无法找到满足条件的进程。
  • 处理资源请求

    • 使用requestResources函数处理资源请求。
    • 检查请求是否合法,即请求量不超过进程的最大需求和系统的可用资源。
    • 试探性分配资源并更新系统状态。
    • 调用isSafeState函数检查系统是否处于安全状态。如果安全,正式分配资源;否则,恢复原状态,拒绝请求。
  • 17
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值