Python实现银行家算法

一、实验目的与实验环境

实验目的:

本题主要内容是模拟实现资源分配。银行家算法是避免死锁的一种重要方法,本实验要求用高级语言编写和调试一个简单的银行家算法程序。加深了解有关资源申请、避免死锁等概念,并体会和了解死锁和避免死锁的具体实施方法。

实验环境:

Windows 10

Python 3.9.13

二、实验内容

1、银行家分配算法

银行家分配算法,顾名思义是来源于银行的借贷业务,一定数量的本金要应多个客户的借贷周转,为了防止银行加资金无法周转而倒闭,对每一笔贷款,必须考察其是否能限期归还。在操作系统中研究资源分配策略时也有类似问题,系统中有限的资源要供多个进程使用,必须保证得到的资源的进程能在有限的时间内归还资源,以供其他进程使用资源。如果资源分配不得到就会发生进程循环等待资源,每个进程都无法继续执行下去的死锁现象。

把每个进程需要和已占有资源的情况记录在进程控制中,假定进程控制块PCB其中“状态”有就绪态、等待态和完成态。当进程在处于等待态时,表示系统不能满足该进程当前的资源申请。“资源需求总量”表示进程在整个执行过程中总共要申请的资源量。显然,每个进程的资源需求总量不能超过系统拥有的资源总数,银行算法进行资源分配可以避免死锁。

2、算法描述

银行家算法:

设进程I提出请求Request[N],则银行家算法按如下规则进行判断。

(1) 如果Request[N]<= Need [I, N],则转(2);否则,出错。

(2) 如果Request[N]<= Available,则转(3);否则,出错。

(3) 系统试探分配资源,修改相关数据:

Available = Available -Request

Allocation = Allocation +Request

Need= Need - Request

(4) 系统执行安全性检查,如安全,则分配成立;否则试探险性分配作废,系统恢复原状,进程等待。

3、安全性检查

(1) 设置两个工作向量Work= Available;Finish[M]=False

(2) 从进程集合中找到一个满足下述条件的进程

Finish[i]=False

Need <=Work

如找到,执行(3);否则,执行(4)

(3) 设进程获得资源,可顺利执行,直至完成,从而释放资源

Work=Work+ Allocation

Finish=True

Go To 2

(4) 如所有的进程Finish[M]=true,则表示安全;否则系统不安全

三、主要算法设计及实现(主要代码)及运行情况说明(运行结果可截图) 

本算法使用Python语言实现。

     0.安装依赖

在控制台中输入pip install numpy,等待其安装完毕。

     1.算法设计

     (0) 构建allocation、need矩阵与available向量

使用numpy包中的array方法构建,向array方法传入一维或二维列表来构建。

     (1) 判断request向量是否满足分配条件

使用numpy包中的all方法判断requset向量每一元素是否均不大于available向量和need矩阵上所对应的行向量。首先先进行各个元素的比较,若满足条件,则在这个位置上填True,否则填False,最终得到这样具有真假值的矩阵,再通过all方法与这个矩阵的每一个元素作and运算,得到最终比较结果(all方法中的axis参数确定轴,对于矩阵,axis=1代表列,axis=0代表行)。若结果为True,尝试分配资源;若结果为False,request向量不能满足分配条件,令该进程等待。

     (2) 修改相关数据,尝试分配资源

修改need、allocation、available,初始化安全序列saftySeq为空,工作向量work、workPlusAllocation等于available。

     (3) 执行安全性检查

使用saftySeq的长度作为安全性检查结束的主要判据,当saftySeq的长度小于进程总数时,除非无法满足进程的资源请求,否则继续进行资源分配。

如果该进程未结束(进程号不在saftySeq中,使用saftySeq来替代Finish),并且对应的need满足此时work向量(即上一状态的workPlusAllocation向量)的要求时,为该进程分配资源,添加到saftySeq中,输出相应信息并修改work与workPlusAllocation向量。

如果对于未结束的全部进程(数目大于0)均未能够满足work>=need条件,即在这一轮寻找结束前未找到,尝试分配失败,并将need、allocation、available恢复到之前的状态。

     2.算法实现(仅展示banker方法)

     3.运行情况说明

测试数据1:

测试数据2:

注释:下方的“request(n)”代表n号进程的请求向量。

     (1)测试数据1 + request(1) = [1, 0, 2]

成功分配,并找到安全序列。

     (2)测试数据1 + request(4) = [3, 3, 0]

无法为P4分配资源。

     (3)测试数据1 + request(0) = [0, 2, 0]

无法为P0分配资源。

     (4)测试数据1 + request(1) = [1, 0 ,2] + request(0) = [0, 2, 0]

无法为P0分配资源。

     (5)测试数据1 + request(1) = [1, 0 ,2] + request(0) = [0, 1, 0]

成功分配。

     (6)测试数据2 + request(1) = [0, 4, 2, 0]

成功分配。

     (7)测试数据2 + request(4) = [0, 6, 2, 0]

无法分配。

四、代码

import numpy as np

allocation = np.array([[0, 1, 0], [2, 0, 0], [3, 0, 2], [2, 1, 1], [0, 0, 2]])
need = np.array([[7, 4, 3], [1, 2, 2], [6, 0, 0], [0, 1, 1], [4, 3, 1]])
available = np.array([3, 3, 2])
# allocation = np.array([[0, 0, 1, 2], [1, 0, 0, 0], [1, 3, 5, 4], [0, 6, 3, 2], [0, 0, 1, 4]])
# need = np.array([[0, 0, 0, 0], [0, 7, 5, 0], [1, 0, 0, 2], [0, 0, 2, 0], [0, 6, 4, 2]])
# available = np.array([1, 5, 2, 0])


def list_convert_nparray(arg):
    return np.array(list(map(int, arg.split(','))))


# index starts from 0
def banker(index, request, allocation, need, available):
    print(index, '  request:', request)
    if np.all(request <= need[index, :], axis=0) and np.all(request <= available, axis=0):
        saftySeq = []
        available -= request
        allocation[index, :] += request
        need[index, :] -= request
        work = workPlusAllocation = available
        sumOfProcess = len(allocation)  # len(allocation) equals the sum of processes
        while len(saftySeq) < sumOfProcess:
            for i in range(0, sumOfProcess):
                cnt = 0
                if len(saftySeq) == sumOfProcess:
                    break
                if i not in saftySeq and np.all(need[i, :] <= workPlusAllocation, axis=0):
                    if len(saftySeq) != 0:
                        work = workPlusAllocation
                    workPlusAllocation = work + allocation[i, :]
                    saftySeq.append(i)
                    print('Process:', i, '  Work:', work, '  Need:', need[i], '  Allocation:', allocation[i],
                          '  Work+Allocation:', workPlusAllocation)
                    cnt += 1
                if i == sumOfProcess - 1 and cnt == 0:
                    available += request
                    allocation[index, :] -= request
                    need[index, :] += request
                    return False
        print('Safty Sequence: ', saftySeq)
        return True
    else:
        return False


if __name__ == '__main__':
    while True:
        print('Need:\n',need)
        print('Allocation:\n',allocation)
        print('Available:',available)
        if banker(int(input("index:")), list_convert_nparray(input("request(split by ,):")), allocation, need, available):
            print("Allocate Successfully")
        else:
            print('Can not Allocate')
        print('-------------------------------')

  • 34
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
银行家算法是一种操作系统中用来避免死锁的算法,下面是一个简单的银行家算法Python 实现示例: ```python # 定义函数实现银行家算法 def banker_algorithm(available, maximum, allocation): n = len(available) # 初始化 need 和 work 矩阵 need = [] for i in range(n): need.append([maximum[i][j] - allocation[i][j] for j in range(len(allocation[i]))]) work = available[:] finish = [False] * n # 模拟银行家算法 safe_seq = [] while False in finish: found = False for i in range(n): if not finish[i] and all([need[i][j] <= work[j] for j in range(len(work))]): finish[i] = True found = True safe_seq.append(i) work = [work[j] + allocation[i][j] for j in range(len(work))] break if not found: return None return safe_seq # 测试银行家算法 if __name__ == '__main__': available = [3, 3, 2] maximum = [[7, 5, 3], [3, 2, 2], [9, 0, 2], [2, 2, 2]] allocation = [[0, 1, 0], [2, 0, 0], [3, 0, 2], [2, 1, 1]] safe_seq = banker_algorithm(available, maximum, allocation) if safe_seq is None: print('No safe sequence found!') else: print('Safe sequence: ', ' -> '.join(['P' + str(i) for i in safe_seq])) ``` 这里的 available、maximum 和 allocation 分别表示系统可用资源、每个进程需要的最大资源和已经分配给每个进程的资源。函数的返回值是银行家算法模拟得到的安全序列,如果找不到安全序列,则返回 None。在上面的示例中,银行家算法得到的安全序列是 P1 -> P3 -> P4 -> P0。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值