考研专题之死锁的形成原因与必要条件,死锁预防、死锁避免(银行家算法)、死锁检测和解除(资源分配图)。

死锁

死锁(Deadlock)是指多个进程在相互竞争资源的过程中因相互等待对方释放资源而进入一种永久阻塞的状态。要理解和解决死锁问题,首先需要了解死锁的形成原因和必要条件,然后再讨论死锁的预防、避免、检测和解除。

死锁的形成原因与必要条件

形成原因:
系统资源的竞争:多个进程竞争有限的资源,比如CPU、内存、I/O设备、文件锁等。
资源分配不当:资源分配策略不当,可能导致一个进程拿到部分资源却无法完成任务,因而进入等待状态。

死锁的四个必要条件(Coffman 条件):
互斥条件(Mutual Exclusion):资源只能被一个进程占用,其他进程如果请求该资源,则必须等待。
持有与等待(Hold and Wait):进程已经持有了至少一个资源,并且还在等待其他被占用的资源。
不剥夺条件(No Preemption):资源不能被强制剥夺,资源只能由持有它的进程主动释放。
环路等待(Circular Wait):存在一个进程等待环路,环中的每个进程都在等待下一个进程所持有的资源。
如果一个系统同时满足这四个条件,那么就可能发生死锁。

死锁的预防

死锁预防策略旨在破坏死锁的四个必要条件中的至少一个,以防止死锁的发生。常见的预防方法包括:

破坏互斥条件:尽可能减少资源的独占性,允许资源共享。例如,使用共享读锁代替独占写锁。
破坏持有与等待条件:要求进程在开始时一次性请求所有所需资源,或者在持有资源时不能请求新的资源。这样避免了进程在持有资源时等待其他资源的情况。
破坏不剥夺条件:允许资源被剥夺,如果一个进程请求的资源不可用,那么它必须释放所有已经持有的资源,然后重新尝试获取所有资源。
破坏环路等待条件:通过对资源进行全局编号,要求进程按照一定的顺序请求资源,从而避免形成环路。

死锁的避免

死锁避免策略基于动态地检测系统的状态,确保系统始终保持在一个“安全状态”中。在安全状态中,资源的分配顺序使得至少有一个进程能够完成执行并释放资源。

银行家算法:这是最著名的死锁避免算法。它模拟银行家分配贷款的过程,通过计算资源分配后的状态是否安全,来决定是否分配资源。如果分配资源后系统进入不安全状态,则拒绝该分配请求。

死锁的检测与解除

即使没有进行预防和避免,系统仍然可以通过检测和解除来应对死锁:

死锁检测
系统定期运行检测算法来检查是否存在死锁。例如,可以构建一个资源分配图并检测是否存在环路。如果发现环路,则表示存在死锁。
在这里插入图片描述

如果系统中剩余的可用资源数足够满足进程的需求,那么这个进程暂时是不会阻塞的,可以顺利地执行下去。
例如下图,如果P1进程已经持有两个R1资源,需要请求1个R2资源;P2进程已经持有一个R1资源和一个R2资源,需要请求一个R1资源。根据以上前提我们不难推断出P1进程是可以正常执行下去的。而P2进程因请求的资源R1已经全部分配出去了,所以P2进程在P1进程执行结束之前一定会处于阻塞状态,在P1进程执行结束之后P2进程才能正常获取R1资源,然后才能正常执行结束。这种情况就不会出现死锁的现象。

在这里插入图片描述

  • 检测死锁的算法
    a. 在资源分配图中,找出既不阻塞又不是孤点的进程(即找出一条有向边与它相连,且该有向边对应的资源申请数量小于等于系统中空闲的资源数量。如上图中R1没有空闲资源,R2有一个空闲资源。若所有连接该进程的边满足上述条件,则这个进程能继续运行直至完成,然后释放它所占用的资源。)。消去它所有的请求边和分配边,使其成为孤立的节点。如下图中P1满足这一条件,所以可以将P1所有的边消去。
    b. 进程P1所释放的资源,可以唤醒因等待这些资源而阻塞的进程,原来的阻塞进程可以变为非阻塞进程。如下图,P2进程就满足这样的条件,根据第一步中的方法进行一系列简化后,若能消除器所有的边,就称该图是完全可简化的。

死锁解除
在这里插入图片描述
一旦检测到死锁,就应该立即解除。

并不是系统中所有的进程都是死锁状态,用死锁检测算法化简资源分配图后,还连着边的那些进程就是死锁进程。

解除死锁的主要方法有:
资源剥夺法:挂起(暂时放到外存上)某些死锁进程,并抢占它的资源,将这些资源分配给其他的死锁进程。但是应防止被挂起的进程长时间得不到资源而饥饿。
撤销进程法(或称终止进程法):强制撤销部分、甚至全部死锁进程,并剥夺这些进程的资源。这种方式的优点是实现简单,但所付出的代价可能会很大。因为有些进程可能已经运行了很长时间,已经接近结束了,一旦被终止可谓功亏一篑,以后还得从头再来。
进程回退法:让一个或多个死锁进程回退到足以避免死锁的地步。这就要求系统要记录进程的历史信息,设置还原点。

在这里插入图片描述

银行家算法

首先我们先了解一个概念就是安全序列

安全序列
所谓安全序列,就是指如果系统按照这种序列分配资源,则每个进程都能顺利完成。只要能找出一个安全序列,系统就是安全状态。当然,安全序列可能有多个。

如果分配了资源之后,系统中找不出任何一个安全序列,系统就进入了不安全状态。这就意味着之后可能所有进程都无法顺利的执行下去。当然,如果有进程提前归还了一些资源,那系统也有可能重新回到安全状态,不过我们在分配资源之前总是要考虑到最坏的情况。

如果系统是在安全状态,就一定不会发生死锁。如果系统处于不安全的状态,就有可能会发生死锁。(系统处于不安全的时候,不一定会发生死锁。但是发生死锁时,系统必然处于不安全的状态。)

因此,在分配资源之前我们要先预判一下分配了资源之后能不能找到一个安全序列,如果能,就可以进行分配。如果不能,就不进行分配。这就是银行家算法的核心思想。

银行家算法
你是一位成功的银行家,手里掌握着100个亿的资金。
有三个企业想找你贷款,分别是企业A、企业B、企业T,为描述方便,简称BAT。
B 表示:“大哥,我最多会跟你借70亿”
A 表示:“大哥,我最多会跟你借40亿”
T 表示:“大哥,我最多会跟你借50亿”
然而…江湖中有个不成文的规矩:如果你借给企业的钱总数达不到企业提出的最大要求,那么不管你之前给企业借了多少钱,那些钱都拿不回来了。
刚开始,BAT三个企业分别从你这儿借了20、10、30亿.….
在这里插入图片描述

1. 第一种情况
在这里插入图片描述
在这里插入图片描述

2. 第二种情况
在这里插入图片描述
在上面这种情景中,A第二次借钱借走20后,安全序列就是T→B→A。

3. 第三种情况
在这里插入图片描述
在上面这种情景中,A第二次借钱借走20后,安全序列就是A→T→B。

银行家算法是荷兰学者 Dikstra 为银行系统设计的,以确保银行在发放现金贷款时,不会发生不能满足所有客户需要的情况。后来该算法被用在操作系统中,用于避免死锁。

核心思想:在进程提出资源申请时,先预判此次分配是否会导致系统进入不安全状态。如果会进入不安全状态,就暂时不答应这次请求,让该进程先阻塞等待。

例题1
BAT 的例子中,只有一种类型的资源——钱,但是在计算机系统中会有多种多样的资源,应该怎么把算法拓展为多种资源的情况呢?

可以把单维的数字拓展为多维的向量。比如:系统中有5个进程 P0~P4, 3种资源 R0~R2,初始数量为(10,5,7),则某一时刻的情况可表示如下:
在这里插入图片描述
此时需要判断当前系统是否处于安全状态,所以需要找出一个安全序列。

  1. 先跟进程一个一个对比,首先可以判断出剩下的资源可以满足进程P1。
    在这里插入图片描述
  2. 然后在从P0进程开始依次比较,找到可以满足的进程为P3。
    在这里插入图片描述
  3. 接下来剩余的资源是可以满足所有进程的需求了,就不用再一一分析了

所以以上实例的中是可以找到一个安全序列的,所以可以判断系统处于安全状态。

例题2
首先系统分配的资源如下
在这里插入图片描述
经对比发现,(3,3,2)可满足 P1、P3,说明无论如何,这两个进程的资源需求一定是可以依次被满足的,因此P1、P3一定可以顺利的执行完,并归还资源。 可把 P1、P3 先加入安全序列。
在这里插入图片描述
剩下的 P0 需要 (8,4,3),P2 需要 (6,5,0),P4 需要 (4,3,4)任何一个进程都不能被完全满足。于是,无法找到任何一个安全序列,说明此时系统处于不安全状态,有可能发生死锁。

例题3
假设系统中有n个进程,m种资源。
每个进程在运行前先声明对各个资源的最大需求数,则可以用一个n * m的二维矩阵表示所有进程对各个资源的最大需求数,不妨称之为最大需求矩阵Max,则Max(i,j) = K,表示进程Pi最多需要K个资源Rj
同理,系统可以用一个n*m的二维矩阵Allocation来表示对所有进程的资源分配情况。
然后再声明一个各个进程还需要多少各类资源的二维矩阵Need,Need = Max - Allocation。
另外,还需要用一个长度为m的一维矩阵Avaliable来表示当前系统中还有多少可用资源。
当某进程Pi向系统申请资源,可用一个长度为m的一维数组Requesti表示本次申请的各种资源量。

在这里插入图片描述
可以用银行家算法预判本次分配是否会导致系统进入不安全的状态。

  1. 如果Requesi[ j ] ≤ Need[ i , j ] (0 ≤ j ≤ m),就进行第2步;否则认为出错。
  2. 如果Requesi[ j ] ≤ Available[ j ] (0 ≤ j ≤ m),就进行第3步;否则表示尚无足够资源,Pi必须等待。
  3. 系统试着把资源分配给进程Pi,并修改相应的数据(并非真的分配,修改数值只是为了做预判):
    Available = Available - Requesti;
    Allocation[ i , j ] = Allocation[ i , j ] + Requesti [ j ];
    Need[ i , j ] = Need[ i , j ] - Requesti [ j ];
  4. 操作系统执行安全性算法,检查此次资源分配后,系统是否处于安全状态。若安全,才正式分配;否则,恢复相应数据,让进程阻寒等待。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值