【Windows】操作系统死锁之银行家算法

目录

基本概念

算法原理

数据结构

算法步骤

安全性检查算法

算法代码

结论


银行家算法(Banker's Algorithm)是一种经典的死锁避免算法,由计算机科学家艾兹格·迪杰斯特拉(Edsger Dijkstra)在1965年为T.H.E系统设计。该算法以银行借贷系统的分配策略为基础,主要用于操作系统中的资源分配,确保系统能够安全地进行资源分配和释放,避免因资源分配不当而导致的死锁。

基本概念

  • 银行家:在算法中,银行家好比操作系统,负责管理和分配资源。
  • 客户:相当于请求资源的进程。
  • 资金:代表操作系统管理的资源。

算法原理

银行家算法的基本思想是,在分配资源之前,先判断系统是否是安全的;若是,则进行资源分配。这里的安全状态指的是系统中存在一个进程序列,使得每个进程在其最大需求得到满足后都能顺利执行完毕,从而避免死锁的发生。

数据结构

为了实现银行家算法,系统需要设置以下数据结构:

  1. Available:长度为m的数组,表示系统当前可用的各类资源数目。
  2. Max:n×m的矩阵,表示每个进程对各类资源的最大需求。
  3. Allocation:n×m的矩阵,表示每个进程当前已分配到的各类资源数目。
  4. Need:n×m的矩阵,表示每个进程尚需的各类资源数目。Need[i][j] = Max[i][j] - Allocation[i][j]。

算法步骤

当进程请求资源时,银行家算法按照以下步骤执行:

  1. 检查请求是否合法
    • 请求量不超过进程的最大需求(Request[i][j] <= Need[i][j])。
    • 请求量不超过系统的可用资源(Request[i][j] <= Available[j])。
  2. 试探性分配
    • 临时分配资源给进程,并更新Available、Allocation和Need矩阵。
  3. 安全性检查
    • 调用安全性算法检查系统是否处于安全状态。
    • 如果系统处于安全状态,则正式分配资源;否则,恢复原状态,拒绝请求。

安全性检查算法

安全性检查算法的基本步骤如下:

  1. 设置两个工作向量Work = Available和Finish(初始时所有进程的Finish均为false)。
  2. 从进程集合中找到一个满足以下条件的进程P_i:
    • Finish[i] == false。
    • Need[i] <= Work。
  3. 假设进程P_i获得资源并顺利执行完毕,释放其占有的资源,更新Work = Work + Allocation[i]。
  4. 设置Finish[i] = true,表示进程P_i已完成。
  5. 重复步骤2至4,直到所有进程的Finish均为true,或找不到满足条件的进程为止。
  6. 如果所有进程的Finish均为true,则系统处于安全状态;否则,系统处于不安全状态。

算法代码

#include <iostream>  
#include <vector>  
#include <algorithm>  
  
using namespace std;  
  
// 假设有n个进程和m种类型的资源  
int n, m; // 进程数n,资源类型数m  
  
// Available数组,表示当前可用的各类资源数目  
vector<int> available;  
  
// Max矩阵,表示每个进程对各类资源的最大需求  
vector<vector<int>> maxDemand;  
  
// Allocation矩阵,表示每个进程当前已分配到的各类资源数目  
vector<vector<int>> allocation;  
  
// Need矩阵,表示每个进程尚需的各类资源数目  
vector<vector<int>> need;  
  
// 安全性检查函数  
bool isSafe() {  
    vector<bool> finish(n, false); // 记录进程是否完成  
    vector<int> work = available; // 工作向量,初始化为Available  
  
    while (true) {  
        bool found = false;  
  
        // 查找可以安全完成的进程  
        for (int i = 0; i < n; i++) {  
            if (!finish[i] && all_of(work.begin(), work.end(), [&](int w, int j) {  
                return w >= need[i][j];  
            })) {  
                // 找到了一个可以安全完成的进程  
                for (int j = 0; j < m; j++) {  
                    work[j] += allocation[i][j]; // 释放该进程所占用的资源  
                }  
                finish[i] = true; // 标记该进程为已完成  
                found = true;  
                break;  
            }  
        }  
  
        // 如果没有找到可以安全完成的进程,则系统进入不安全状态  
        if (!found) {  
            return false;  
        }  
  
        // 如果所有进程都已完成,则系统处于安全状态  
        if (all_of(finish.begin(), finish.end(), ::true)) {  
            return true;  
        }  
    }  
}  
  
// 模拟请求资源函数  
bool requestResources(int process, const vector<int>& request) {  
    // 检查请求是否合法  
    if (any_of(request.begin(), request.end(), [&](int r, int j) {  
        return request[j] > need[process][j] || request[j] > available[j];  
    })) {  
        cout << "Error: Request exceeds maximum claim or available amount\n";  
        return false;  
    }  
  
    // 尝试分配资源  
    for (int j = 0; j < m; j++) {  
        available[j] -= request[j];  
        allocation[process][j] += request[j];  
        need[process][j] -= request[j];  
    }  
  
    // 检查分配后系统是否安全  
    if (!isSafe()) {  
        // 如果不安全,则撤销分配  
        for (int j = 0; j < m; j++) {  
            available[j] += request[j];  
            allocation[process][j] -= request[j];  
            need[process][j] += request[j];  
        }  
        cout << "Error: System is not in a safe state after allocation\n";  
        return false;  
    }  
  
    cout << "Resources allocated successfully to process " << process << endl;  
    return true;  
}  
  
int main() {  
    // 初始化参数  
    n = 5; // 进程数  
    m = 3; // 资源类型数  
  
    // 初始化Available数组  
    available = {3, 3, 2};  
  
    // 初始化Max、Allocation、Need矩阵(这里仅作为示例)  
    maxDemand = {  
        {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矩阵  
    need.resize(n, vector<int>(m)); 
...... 
  }

结论

银行家算法通过模拟资源分配和检查系统是否进入安全状态,来避免死锁的发生。它要求系统在进行资源分配前进行安全性检查,确保分配后系统仍处于安全状态。这种算法在操作系统中得到了广泛应用,是避免死锁的一种有效手段。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

爱编程的小猴

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

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

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

打赏作者

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

抵扣说明:

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

余额充值