死锁的产生和避免

死锁的发生必须具备以下四个 必要条件
   1)互斥条件: 指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。
   2)请求和保持条件: 指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
   3)不剥夺条件: 指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。

  4)环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源


理解了死锁的原因,尤其是产生死锁的四个必要条件,就可以最大可能地避免、预防和解除死锁。所以,在系统设计、进程调度等方面注意如何不让这四个必要条件成立,如何确定资源的合理分配算法,避免进程永久占据系统资源。此外,也要防止进程在处于等待状态的情况下占用资源,在系统运行过程中,对进程发出的每一个系统能够满足的资源申请进行动态检查,并根据检查结果决定是否分配资源,若分配后系统可能发生死锁,则不予分配,否则予以分配。因此,对资源的分配要给予合理的规划。

有序资源分配法

  这种算法资源按某种规则系统中的所有资源统一编号(例如打印机为1、磁带机为2、磁盘为3、等等),申请时必须以上升的次序。系统要求申请进程:
  1、对它所必须使用的而且属于同一类的所有资源,必须一次申请完;
  2、在申请不同类资源时,必须按各类设备的编号依次申请。例如:进程PA,使用资源的顺序是R1,R2; 进程PB,使用资源的顺序是R2,R1;若采用动态分配有可能形成环路条件,造成死锁。
  采用有序资源分配法:R1的编号为1,R2的编号为2;
  PA:申请次序应是:R1,R2
  PB:申请次序应是:R1,R2
  这样就破坏了环路条件,避免了死锁的发生

银行算法

  避免死锁算法中最有代表性的算法是Dijkstra E.W 于1968年提出的 银行家算法
  该算法需要检查申请者对资源的最大需求量,如果系统现存的各类资源可以满足申请者的请求,就满足申请者的请求。
  这样申请者就可很快完成其计算,然后释放它占用的资源,从而保证了系统中的所有进程都能完成,所以可避免死锁的发生。

编辑本段死锁排除的方法

  1、撤消陷于死锁的全部进程;
  2、逐个撤消陷于死锁的进程,直到死锁不存在;
  3、从陷于死锁的进程中逐个强迫放弃所占用的资源,直至死锁消失。
  4、从另外一些进程那里强行剥夺足够数量的资源分配给死锁进程,以解除死锁状态


死锁的预防和检测代价都是很大的,所以一般系统都不用,经常用的方法就是watchdog,如果程序长时间没有反应(一般就是死锁或是无限循环),watchdog重新复位程序。


### 死锁预防与死锁避免的概念及主要区别 #### 概念定义 - **死锁预防**是一种静态策略,通过破坏死锁产生的四个必要条件之一(互斥条件、请求保持条件、不剥夺条件或循环等待条件),确保系统永远不会进入死锁状态[^2]。这种方法通常在系统设计阶段实现,通过预先设定资源分配算法来消除死锁的可能性。 - **死锁避免**是一种动态策略,在资源分配时进行安全性检查,以确保系统的资源分配不会导致死锁。如果某个资源分配会导致系统进入不安全状态,则该分配会被拒绝。银行家算法是典型的死锁避免方法[^1]。 #### 主要区别 | 区别点 | 死锁预防 | 死锁避免 | |----------------|---------------------------------------------|---------------------------------------------| | **策略类型** | 静态策略 | 动态策略 | | **实现方式** | 破坏死锁的四个必要条件之一 | 在每次资源分配前进行安全性检查 | | **执行时机** | 系统设计阶段,提前确定资源分配规则 | 资源分配运行时,实时检测 | | **资源利用率** | 较低,因为某些资源可能被限制使用 | 较高,允许更多灵活的资源分配 | | **复杂性** | 简单,但可能导致资源浪费 | 复杂,需要实时计算安全性 | | **安全性** | 安全可靠,完全避免死锁 | 安全可靠,但在某些情况下可能无法分配资源 | #### 示例代码:银行家算法死锁避免) 以下是一个简单的银行家算法实现示例,用于演示如何在资源分配中避免死锁: ```python def is_safe(state, available, max_claim, allocation): need = max_claim - allocation work = available.copy() finish = [False] * len(state) for i in range(len(state)): if not finish[i] and (need[i] <= work).all(): work += allocation[i] finish[i] = True i = -1 # Restart the loop return all(finish) # 示例输入 state = ['P0', 'P1', 'P2'] available = [3, 3, 2] max_claim = [[7, 5, 3], [3, 2, 2], [9, 0, 2]] allocation = [[0, 1, 0], [2, 0, 0], [3, 0, 2]] if is_safe(state, available, max_claim, allocation): print("系统处于安全状态") else: print("系统可能进入死锁状态") ``` #### 总结 死锁预防死锁避免虽然都旨在防止死锁的发生,但它们的实现方式适用场景有所不同。死锁预防是一种静态方法,简单可靠但可能导致资源利用率低下;而死锁避免是一种动态方法,能够更高效地利用资源,但实现起来更加复杂。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值