避免死锁 —— 银行家算法

综述

以下概念引用与百度百科

银行家算法(Banker’s Algorithm)是一个避免死锁(Deadlock)的著名算法,是由艾兹格·迪杰斯特拉在1965年为T.H.E系统设计的一种避免死锁产生的算法。它以银行借贷系统的分配策略为基础,判断并保证系统的安全运行。

做作业时遇到银行家算法的题,同时本着想要加深一下对于避免死锁和银行家算法的理解,所以选择用程序实现一下该算法。本来想使用C++进行编写,毕竟老ACM选手了,但是学完Python之后没怎么用过,所以就用Python实现了。

算法

操作时需要使用到矩阵,用Python本身带的列表创建矩阵有点麻烦,所以使用numpy包所带的矩阵进行创建。
Pycharm没有带有numpy包,使用需要到File > Setting > Project:Study > Python Interpreter中添加numpy包。
算法中所需要的数据结构

  • 可利用资源向量 A v a i l a b l e Available Available
    是个含有 m m m个元素的数组,其中的每一个元素代表一类可利用的资源数目。如果 A v a i l a b l e [ j ] = K Available[j]=K Available[j]=K,则表示系统中现有Rj类资源K个。
  • 最大需求矩阵 M a x Max Max
    这是一个 n × m n×m n×m的矩阵,它定义了系统中 n n n个进程中的每一个进程对m类资源的最大需求。如果 M a x [ i , j ] = K Max[i,j]=K Max[i,j]=K,则表示进程i需要Rj类资源的最大数目为 K K K
  • 分配矩阵 A l l o c a t i o n Allocation Allocation
    这也是一个 n × m n×m n×m的矩阵,它定义了系统中每一类资源当前已分配给每一进程的资源数。如果 A l l o c a t i o n [ i , j ] = K Allocation[i,j]=K Allocation[i,j]=K,则表示进程i当前已分得 R j R_j Rj类资源的 数目为K。
  • 需求矩阵 N e e d Need Need
    这也是一个 n × m n×m n×m的矩阵,用以表示每一个进程尚需的各类资源数。如果 N e e d [ i , j ] = K Need[i,j]=K Need[i,j]=K,则表示进程i还需要 R j R_j Rj类资源 K K K个,方能完成其任务。
    N e e d [ i , j ] = M a x [ i , j ] − A l l o c a t i o n [ i , j ] Need[i,j]=Max[i,j]-Allocation[i,j] Need[i,j]=Max[i,j]Allocation[i,j]

安全检查

  1. 设置两个工作向量Work=AVAILABLE;FINISH
  2. 从进程集合中找到一个满足下述条件的进程,
    FINISH==false;
    NEED<=Work;
    如找到,执行(3);否则,执行(4)
  3. 设进程获得资源,可顺利执行,直至完成,从而释放资源。
    Work=Work+ALLOCATION;
    Finish=true;
    GOTO 2
  4. 如所有的进程 F i n i s h = t r u e Finish= true Finish=true,则表示安全;否则系统不安全。

代码

def check():
    work = Available.copy()
    finish = [False for it in range(n)]

    ans = "安全序列为:"
    for num in range(n):
        for it in range(n):
            if not finish[it]:
                cnt = 0
                for jt in range(m):
                    if Need[it][jt] <= work[jt]:
                        cnt = cnt + 1

                if cnt == m:
                    ans = ans + str(it)
                    finish[it] = True
                    for jt in range(m):
                        work[jt] += Allocation[it][jt]

    if False in finish:
        return "系统处于不安全状态"
    else:
        return ans

银行家算法

设进程 c u s n e e d cusneed cusneed提出请求 R E Q U E S T [ i ] REQUEST [i] REQUEST[i],则银行家算法按如下规则进行判断。

  1. 如果REQUEST [cusneed] [i]<= NEED[cusneed][i],则转(2);否则,出错。
  2. 如果REQUEST [cusneed] [i]<= AVAILABLE[i],则转(3);否则,等待。
  3. 系统试探分配资源,修改相关数据:
    AVAILABLE[i]-=REQUEST[cusneed][i];
    ALLOCATION[cusneed][i]+=REQUEST[cusneed][i]
    NEED[cusneed][i]-=REQUEST[cusneed][i];
  4. 系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。

代码

def request():
    t = int(input("请输入哪个进程请求资源:"))
    Request = input("请输入请求的资源数,用字符串输入:").split(' ')
    Request = [int(it) for it in Request]

    for it in range(m):
        if Request[it] > Need[t][it]:
            return "需要资源数超过它所需求的最大值"

    for it in range(m):
        if Request[it] > Available[it]:
            return "尚无足够资源"

    for it in range(m):
        Available[it] -= Request[it]
        Allocation[t][it] += Request[it]
        Need[t][it] -= Request[it]

    if check() == "系统处于不安全状态":
        Available[it] += Request[it]
        Allocation[t][it] -= Request[it]
        Need[t][it] += Request[it]
        return "分配后系统处于不安全状态"
    else:
        return "已分配"

总代码

# 编写人: 筱翼深凉
# 创建时间: 2022/4/16 17:48
# 编写人: 筱翼深凉
# 创建时间: 2022/4/16 16:28

import numpy as np


def check():
    work = Available.copy()
    finish = [False for it in range(n)]

    ans = "安全序列为:"
    for num in range(n):
        for it in range(n):
            if not finish[it]:
                cnt = 0
                for jt in range(m):
                    if Need[it][jt] <= work[jt]:
                        cnt = cnt + 1

                if cnt == m:
                    ans = ans + str(it)
                    finish[it] = True
                    for jt in range(m):
                        work[jt] += Allocation[it][jt]

    if False in finish:
        return "系统处于不安全状态"
    else:
        return ans


def request():
    t = int(input("请输入哪个进程请求资源:"))
    Request = input("请输入请求的资源数,用字符串输入:").split(' ')
    Request = [int(it) for it in Request]

    for it in range(m):
        if Request[it] > Need[t][it]:
            return "需要资源数超过它所需求的最大值"

    for it in range(m):
        if Request[it] > Available[it]:
            return "尚无足够资源"

    for it in range(m):
        Available[it] -= Request[it]
        Allocation[t][it] += Request[it]
        Need[t][it] -= Request[it]

    if check() == "系统处于不安全状态":
        Available[it] += Request[it]
        Allocation[t][it] -= Request[it]
        Need[t][it] += Request[it]
        return "分配后系统处于不安全状态"
    else:
        return "已分配"


n = int(input("请输入进程数:"))  # 进程个数
m = int(input("请输入临界资源数:"))  # 临界资源数

# Max最大资源需求数,Need需要的资源数,Allocation已分配的资源数,Available空闲的资源数
Max, Allocation, Need = np.zeros([n, m], int), np.zeros([n, m], int), np.zeros([n, m], int)
Max.tolist(), Need.tolist(), Allocation.tolist()

for i in range(n):
    data1 = input("请输入第" + str(i) + "个进程最大资源需求数,用字符串输入:").split(' ')
    data2 = input("请输入第" + str(i) + "个进程已分配的资源数,用字符串输入:").split(' ')
    for j in range(m):
        Max[i][j] = int(data1[j])
        Allocation[i][j] = int(data2[j])
        Need[i][j] = int(data1[j]) - int(data2[j])

Available = input("请输入可利用资源数,用字符串输入:").split(' ')
Available = [int(x) for x in Available]

while True:
    option = input("请输入操作(Q 退出,C 检查是否安全,R 请求资源)")
    if option == 'Q':
        break
    elif option == 'C':
        print(check())
    elif option == 'R':
        print(request())
    else:
        print("输入错误")

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
银行家算法是一种资源分配算法,旨在避免系统进入死锁状态。下面是一个简单的示例代码,演示如何使用银行家算法避免死锁: ```c++ #include <iostream> using namespace std; const int P = 5; // 进程数量 const int R = 3; // 资源数量 int available[R] = {3, 3, 2}; // 系统可用资源数量 int maxm[P][R] = {{7, 5, 3}, {3, 2, 2}, {9, 0, 2}, {2, 2, 2}, {4, 3, 3}}; // 进程最大需求量 int allocation[P][R] = {{0, 1, 0}, {2, 0, 0}, {3, 0, 2}, {2, 1, 1}, {0, 0, 2}}; // 进程已分配的资源数量 int need[P][R]; // 进程还需要的资源数量 bool finish[P] = {false}; // 每个进程是否已完成 void calculate_need() { for (int i = 0; i < P; i++) { for (int j = 0; j < R; j++) { need[i][j] = maxm[i][j] - allocation[i][j]; } } } bool is_safe() { int work[R]; for (int i = 0; i < R; i++) { work[i] = available[i]; } bool finish_all = false; while (!finish_all) { bool found = false; for (int i = 0; i < P; i++) { if (!finish[i]) { bool satisfy = true; for (int j = 0; j < R; j++) { if (need[i][j] > work[j]) { satisfy = false; break; } } if (satisfy) { found = true; finish[i] = true; for (int j = 0; j < R; j++) { work[j] += allocation[i][j]; } } } } if (!found) { finish_all = true; for (int i = 0; i < P; i++) { if (!finish[i]) { return false; } } } } return true; } int main() { calculate_need(); if (is_safe()) { cout << "The system is safe." << endl; } else { cout << "The system is unsafe." << endl; } return 0; } ``` 在上面的代码中,我们使用了一个 `calculate_need()` 函数来计算每个进程还需要的资源数量。然后,我们使用 `is_safe()` 函数来验证系统是否处于安全状态。 在 `is_safe()` 函数中,我们先初始化一个数组 `work`,用来表示系统当前可用的资源数量。然后,我们使用一个循环来遍历所有的进程,如果发现有一个进程未完成并且它的需求可以被满足,就将它标记为已完成,并且将它所需的资源数量加入到 `work` 数组中。如果在遍历所有进程后没有找到可以完成的进程,则说明系统处于不安全状态。 如果 `is_safe()` 函数返回 `true`,则说明系统处于安全状态,可以继续分配资源。如果返回 `false`,则说明系统处于不安全状态,需要等待资源释放或者回收资源,以避免死锁

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值