IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 银行家算法之Python实现[操作系统实验] -> 正文阅读

[数据结构与算法]银行家算法之Python实现[操作系统实验]

银行家算法

银行家算法是著名的死锁避免算法,其思想是:把操作系统视为银行家,操作系统管理的资源相当于银行家管理的资金,进程向操作系统请求分配资源相当于用户向银行家贷款。操作系统按照银行家制定的规则为进程分配资源。进程运行之前先声明对各种资源的最大需求量,当进程在执行中继续申请资源时,先测试该进程已占用的资源数与本次申请的资源数之和是否超过该进程声明的最大需求量。若超过则拒绝分配资源,若未超过则再测试系统现存的资源能否满足该进程尚须的最大资源量,若能满足则按当前的申请量分配资源,否则也要推迟分配。

问题描述

设计程序模拟避免死锁的银行家算法的工作过程。假设系统中有n个进程: P 1 , P 2 , … , P n P_1,P_2,\dots,P_n P1?,P2?,,Pn?,有m类可分配资源 R 1 , … , R m R_1,\dots,R_m R1?,,Rm?,在某时刻,进程 P i P_i Pi?已分配到的j类资源为 A l l o c a t i o n [ i ] [ j ] Allocation[i][j] Allocation[i][j]个,还需要j类资源 n e e d [ i ] [ j ] need[i][j] need[i][j]个,目前系统剩余j类资源 A v a i l a b l e [ j ] Available[j] Available[j]个。

实验要求

  1. 判断当前状态是否安全。若安全,给出安全序列;若不安全,给出理由。
  2. 对于下一个时刻,某个进程提出资源请求Request(R1,…,Rm),使用银行家算法作为判读是否相应该响应该请求的决策依据。
  3. 输入某时刻的资源分配表和进程请求信息,输出安全序列分析,给出决策方案。

数据结构描述

  • 系统可用资源向量 A v a i l a b l e [ m ] Available[m] Available[m]
  • 最大需求矩阵 M a x [ n ] [ m ] Max[n][m] Max[n][m]
  • 分配矩阵 A l l o c a t i o n [ n ] [ m ] Allocation[n][m] Allocation[n][m]
  • 需求矩阵 N e e d [ n ] [ m ] Need[n][m] Need[n][m]

其中,n是进程数量,m是资源种类数量。

算法描述

  • 输入:T0时刻的资源分配表
  • 输出:Pi发出资源请求后,进行的安全序列分析表和安全序列。若不安全,则给出不安全产生的原因。
  1. 进程Pi发出请求 R e q u e s t i Request_i Requesti?,首先检查其合法性,若 R e q u e s t i ≤ N e e d [ i ] Request_i\le Need[i] Requesti?Need[i]则继续进行,否则报错;
  2. R e q u e s t i ≤ A v a i l a b l e Request_i\le Available Requesti?Available,则继续进行,否则认为当前资源不足,不响应当前请求;
  3. 系统试探性把资源分配给进程Pi:
    A v a i l a b l e ? = R e q u e s t i Available-=Request_i Available?=Requesti?
    A l l o c a t i o n [ i ] + = R e q u e s t i Allocation[i]+=Request_i Allocation[i]+=Requesti?
    N e e d [ i ] ? = R e q u e s t i Need[i]-=Request_i Need[i]?=Requesti?
  4. 使用银行家算法进行安全性检查,检查此次资源分配后,系统是否处于安全状态,若安全才正式将资源分配给进程Pi;否则本次的试探作废,Pi继续等待。安全性检查算法如下:
    1. 设置工作量 W o r k [ m ] Work[m] Work[m],表示系统中剩余的可用资源数目。在安全性检查开始时,置Work=Available;
    2. 初始时安全序列为空;
    3. 遍历Need矩阵行,找出一行k,该行对应的Pk不在安全序列中,且 N e e d [ k ] ≤ W o r k Need[k]\le Work Need[k]Work,将对应Pk插入安全序列,若找不到则跳过下一步;
    4. 更新 W o r k = W o r k + A l l o c a t i o n [ k ] Work=Work+Allocation[k] Work=Work+Allocation[k],表征Pk获取资源并运行结束后,将资源释放的过程。返回上步,继续寻找下一个可以分配资源的进程;
    5. 此时,安全序列中若存在所有进程,则系统处于安全状态,否则系统不安全。

算法流程图

在这里插入图片描述

结果分析

设置n=5;m=3
T0时刻资源分配表
Available: [3 3 2]
P Allocation Need
0 [0 1 0] [7 4 3]
1 [2 0 0] [1 2 2]
2 [3 0 2] [6 0 0]
3 [2 1 1] [0 1 1]
4 [0 0 2] [4 3 1]

(1)P1请求资源,Request1 = [1, 0, 2]
?VALID CHECK PASSED!
?RESOURCE CHECK PASSED!
通过合法性和资源检查,假定为P1分配资源,然后进行安全性检查:
P Work Need Allocation Work+Allocation
1 [2 3 0] [0 2 0] [3 0 2] [5 3 2]
3 [5 3 2] [0 1 1] [2 1 1] [7 4 3]
0 [7 4 3] [7 4 3] [0 1 0] [7 5 3]
2 [7 5 3] [6 0 0] [3 0 2] [10 5 5]
4 [10 5 5] [4 3 1] [0 0 2] [10 5 7]
?SAFE CHECK PASSED!
Secured Sequence is [1, 3, 0, 2, 4].
通过安全性检查,为P1分配资源,输出当前资源分配信息:
Available: [2 3 0]
P Allocation Need
0 [0 1 0] [7 4 3]
1 [3 0 2] [0 2 0]
2 [3 0 2] [6 0 0]
3 [2 1 1] [0 1 1]
4 [0 0 2] [4 3 1]

(2)T1时刻,P4继续请求资源
Request4 = [3, 3, 0]
?VALID CHECK PASSED!
??REQUEST EXCEEDS AVAILABLE!
Request4<=Need[4],但Request4>Available,资源检查失败,P4等待分配资源

(3)T2时刻,P0请求资源
Request0 = [0, 2, 0]
?VALID CHECK PASSED!
?RESOURCE CHECK PASSED!
??SAFE CHECK FAILED!
通过合法性和资源检验,假设为P0分配资源,此时Available不满足银行家算法,安全性检验失败,若为P0分配资源会导致死锁,故返回原始状态。

(4)T3时刻,P3请求资源
Request3 = [0, 2, 1]
??Exception: ERROR!P3 REQUEST EXCEEDS ITS NEED!
报错,因为请求资源大于了需求量!

在这里插入图片描述

附录:代码

# @Sylvan Ding 2022.05.31


import numpy as np


def err(P):
    raise Exception("ERROR!P{} REQUEST EXCEEDS ITS NEED!".format(P))


def valid_check(P, Request, Need):
    if np.sum(Request > Need[P, :]):
        err(P)
    print("\033[0;32mVALID CHECK PASSED!\033[0m")


def resource_check(Request, Available):
    if np.sum(Request > Available):
        print("\033[0;31mREQUEST EXCEEDS AVAILABLE!\033[0m")
        return False
    else:
        print("\033[0;32mRESOURCE CHECK PASSED!\033[0m")
        return True


def safe_check(Work, Need, Allocation, n):
    Q = []
    while True:
        i = 0
        while i < n:
            if i not in Q and not np.sum(Need[i, :] > Work):
                Q.append(i)
                temp = Work.copy()
                Work = Work + Allocation[i, :]
                print_safe_check(i, temp, Need, Allocation, Work)
                break
            i = i + 1
        if i == n:
            break
    if len(Q) < n:
        print("\033[0;31mSAFE CHECK FAILED!\033[0m")
        return False
    else:
        print("\033[0;32mSAFE CHECK PASSED!\nSecured Sequence is {}.\033[0m".format(Q))
        return True


def try_allocate(Available, Allocation, Need, Request, P):
    Available = Available - Request
    Allocation[P, :] = Allocation[P, :] + Request
    Need[P, :] = Need[P, :] - Request
    return Available, Need, Allocation


def print_safe_check(k, Work, Need, Allocation, Work_Allocation):
    print("{}\t {}\t {}\t {}\t {}".format(k,
                                          Work,
                                          Need[k, :],
                                          Allocation[k, :],
                                          Work_Allocation))


def print_resource(Available, Need, Allocation, n):
    print("Current resource information: ")
    print("Available: {}".format(Available))
    print("P\t Allocation\t Need")
    for i in range(n):
        print("{}\t {}\t {}".format(i, Allocation[i, :], Need[i, :]))


def print_request_info(P, Request):
    print("\033[0;33mP{} requests {}.\033[0m".format(P, Request))


def Banker(n, Available, Max, Allocation, P, Request):
    """
    :param n: int
    :param Available: array[n][m]
    :param Max: array[n][m]
    :param Allocation: array[n][m]
    :param P: index of process to request
    :param Request: array[m]
    :return: Available, Need, Allocation
    """
    print_request_info(P, Request)
    Available = np.asarray(Available)
    Max = np.asarray(Max)
    Allocation = np.asarray(Allocation)
    Request = np.asarray(Request)
    Need = Max - Allocation
    print_resource(Available, Need, Allocation, n)
    valid_check(P, Request, Need)
    if (resource_check(Request, Available) and
            safe_check(*try_allocate(Available.copy(),
                                     Allocation.copy(),
                                     Need.copy(),
                                     Request, P), n)):
        Available, Need, Allocation = try_allocate(Available.copy(),
                                                   Allocation.copy(),
                                                   Need.copy(),
                                                   Request, P)
        print_resource(Available, Need, Allocation, n)
    return Available, Need, Allocation


def BankerAlgorithm():
    n = 5
    # m = 3
    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]]

    P1 = 1
    Request1 = [1, 0, 2]
    Available, Need, Allocation = Banker(n, Available, Max, Allocation, P1, Request1)

    P4 = 4
    Request4 = [3, 3, 0]
    Available, Need, Allocation = Banker(n, Available, Max, Allocation, P4, Request4)

    P0 = 0
    Request0 = [0, 2, 0]
    Available, Need, Allocation = Banker(n, Available, Max, Allocation, P0, Request0)

    P3 = 3
    Request3 = [0, 2, 1]
    Banker(n, Available, Max, Allocation, P3, Request3)


if __name__ == '__main__':
    BankerAlgorithm()

原创文章:转载请注明出处 ?? Sylvan Ding

参考文献

  1. 2023年操作系统考研复习指导/王道论坛考研组编.——北京:电子工业出版社,2021.12
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-06-08 19:12:49  更:2022-06-08 19:13:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 1:38:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码