栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

【操作系统】避免死锁的算法——银行家算法

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【操作系统】避免死锁的算法——银行家算法

学习目标:

1、了解多道程序系统中,多个进程并发执行的资源分配
2、掌握死锁产生的原因,产生死锁的必要条件和处理死锁的基本方法
3、掌握银行家算法,了解资源在进程并发执行中的资源分配策略


学习内容:

考虑某一系统,它有3类资源R1,R2,R3,有5个并发进程P0,P1,P2,P3,P4。资源分配情况如下:

如果进程依次有资源请求:P0为(1,1,0),P1为(2,3,0),P3为(0,1,1),系统将怎样进行资源分配?


为什么会产生死锁?

首先我们需要知道在多道处理系统中进程是并发执行,共享消耗系统资源,这样可以提高系统的资源利用率。
比如说:有两个进程P1,P2需要竞争R1,R2两个资源,每个进程都要单独占用这两个资源一段时间

def P1():
{
	request R1
	request R2
	release R1
	release R2
}
def P2():
{
	request R2
	request R1
	release R2
	release R1
}

图中描述了各个进程是如何获取释放共享资源的过程:

P1获得了R1,P2获得了R2,由于继续执行过程中P2阻塞在R1上,R1被P1占用没有释放,但是P1要获得的R2又被P2占用着,就发生了死锁现象。
用严谨科学的术语解释死锁:在多道程序系统中,一组进程中的每一个进程均无限期的等待被该组进程中的另一个进程占用且永远不会释放的资源,这种现象称作为系统的死锁状态。

产生死锁的原因

归纳起来有两点:

  • 竞争资源。多个进程所共享的资源不够,引起进程间的抢夺。我家养了两条狗,但只有一个碗,每次给的饭不够两个狗吃,那不得打起来嘛!
  • 进程推进的顺序不当,进程运行过程中释放资源的顺序不当,导致死锁。还是两条狗,假如说大黄先吃,吃完了再让二黄吃,这样两条狗就不会打架
产生死锁的必要条件
  • 互斥条件。即某一段时间资源只能被一个进程占用
  • 请求和保持条件。当进程因请求资源而阻塞时,对已经获取的资源保持不妨
  • 不剥夺条件。进程在获得的资源未使用完之前,不能被剥夺,只能自己释放
  • 环路等待条件。在发生死锁时,必然存在一个进程-资源的环形链。
实验结果: 代码:
import numpy as np


class BankerAlgorithm():
    def __init__(self, available, max, allocation, need):
        """
        初始化参数
        :param available: 可利用资源向量
        :param max: 最大需求矩阵
        :param allocation: 分配矩阵
        :param need: 需求矩阵
        """
        self.available = available
        self.max = max
        self.allocation = allocation
        self.need = need

    def Request(self, P, request):
        """
        请求资源
        :param P: 进程号,从0开始
        :param request: 所请求的资源向量
        :return: 若成功,打印安全序列,进行分配;否则,拒绝请求。
        """
        # 判断请求向量是否小于需求向量
        length = len(request)
        i = 0
        for i in range(length):
            if request[i] > self.need[P][i]:
                break
        if i != len(request) - 1:
            print("进程{0}所需资源超过它所宣布的最大值n".format(P))
            return

        # 判断请求向量是否小于可用资源向量
        j = 0
        for j in range(length):
            if request[i] > self.available[i]:
                break
        if j != length - 1:
            print("尚未足够的资源供{}使用", P)
            return

        # 试分配
        avi_temp = self.available
        all_temp = self.allocation
        need_temp = self.need

        for k in range(length):
            avi_temp[k] = avi_temp[k] - request[k]
            all_temp[P][k] = all_temp[P][k] + request[k]
            need_temp[P][k] = need_temp[P][k] - request[k]

        # 执行安全性算法,若存在安全序列,执行分配
        if self.Security():
            self.need = need_temp
            self.allocation = all_temp
            self.available = avi_temp
            print("请求成功!各数据结构修改为nNeed={0}nAllocation={1}nAvailable{2}n".format(self.need, self.allocation,
                                                                                   self.available))

        else:
            print("如此分配会导致系统处于不安全状态,拒绝本次分配")
            return

    def Security(self):
        """
        安全性算法,检验试分配后系统是否处于安全状态。
        :return: 若分配后系统处于安全状态,打印安全序列并返回True;否则返回False
        """
        work = self.available
        finish = [False for i in range(self.need.shape[0])]
        pro_number = self.need.shape[0]
        pro_list = [i for i in range(pro_number)]
        length = self.need.shape[1]
        secureSeq = ""

        # 寻找安全序列
        for k in range(pro_number):
            for i in pro_list:
                flag = 1
                for j in range(length):
                    if self.need[i][j] > work[j]:
                        flag = 0
                        break

                if flag and finish[i] is False:
                    work += self.allocation[i]
                    finish[i] = True
                    secureSeq += str(i) + "->"
                    pro_list.remove(i)
                    break

        for i in range(len(finish)):
            if finish[i] is not True:
                return False
        print("存在安全序列为{0}".format(secureSeq.strip("->")))
        return True


if __name__ == "__main__":
    avi = np.array([3, 3, 2])  # 可利用资源向量

    all = np.array([[2, 3, 1],
                    [1, 5, 2],
                    [2, 1, 0],
                    [3, 1, 2],
                    [1, 1, 1]])  # 分配矩阵
    max = np.array([[10, 7, 3],
                    [5, 6, 4],
                    [4, 3, 1],
                    [4, 2, 5],
                    [3, 5, 2]])  # 最大需求矩阵

    need = max - all  # 需求矩阵

    Test = BankerAlgorithm(avi, max, all, need)
    Test.Request(0, np.array([1, 1, 0]))
    Test.Request(1, np.array([2, 3, 0]))
    Test.Request(2, np.array([0, 1, 1]))

结果:
存在安全序列为2->1->3->0->4
请求成功!各数据结构修改为
Need=[[7 3 2]
 [4 1 2]
 [2 2 1]
 [1 1 3]
 [2 4 1]]
Allocation=[[3 4 1]
 [1 5 2]
 [2 1 0]
 [3 1 2]
 [1 1 1]]
Available[12 14  8]

进程1所需资源超过它所宣布的最大值

存在安全序列为0->1->2->3->4
请求成功!各数据结构修改为
Need=[[7 3 2]
 [4 1 2]
 [2 1 0]
 [1 1 3]
 [2 4 1]]
Allocation=[[3 4 1]
 [1 5 2]
 [2 2 1]
 [3 1 2]
 [1 1 1]]
Available[22 26 14]


Process finished with exit code 0

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/950201.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号