死锁

本文深入探讨了计算机系统中的死锁问题,包括死锁的定义、产生的四个必要条件,以及如何预防和避免死锁。文章介绍了破坏互斥、不可剥夺、占有且申请、环路等待条件的方法,同时提到了银行家算法作为避免死锁的一种策略。此外,还讨论了死锁检测和恢复的策略,如重新启动系统、撤销进程和进程回退。最后,以经典案例哲学家就餐问题来进一步阐述死锁的概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、前景知识了解

(进程间的同步与互斥)https://blog.youkuaiyun.com/zhourong0511/article/details/80266137


二、死锁(死亡拥抱)

1. 什么是死锁?

在计算机系统中,有很多一次只能由一个进程使用的资源,如:打印机,磁带机等。
在多道程序设计中,若干个进程往往要共享这类资源,而且一个进程所需要的资源不止一个。这样,会出现若干个进程竞争有效资源,有推进顺序不当,从而使得多个进程循环等待它方占有的资源而无限期地僵持下去的局面。——这种状态称之为死锁。

2. 死锁产生的原因:

资源有限且操作不当。


3. 死锁产生的条件:(4个)

①互斥条件

某个进程要么已经分给了一个进程,要么就是可用的。
即:资源非共享:某个资源在一段时间内只能由一个进程占有,不能同时被两个或两个以上的进程占有。

②不可剥夺条件

进程所获得的资源在未使用完毕之前,其他资源申请者不能强行从该进程手中剥夺资源,除非资源占有者自己主动释放资源。

③占有且申请条件

一个进程已经占有一个资源,但是它仍然可以申请新的资源。由于该资源已经被另一个进程所占有,此时该进程阻塞,进入等待队列。但是在等待新资源之时,该进程仍然可以继续占用已占有的资源。

④环路等待条件

死锁发生之时,系统中一定有两个或两个以上的进程形成的一个环路(等待队列),环路中的每一个进程都在等待下一个进程释放的资源。

以上四个条件发生死锁时会同时发生,换句话说,只要有一个必要条件不满足,死锁就可以排除。


4. 死锁的预防:

防止死锁的发生只需破坏死锁产生的四个必要条件之一即可。

①破坏互斥条件

如果允许系统资源都能共享使用,系统便不会进入死锁状态。但有些临界资源只能互斥使用,根本不能同时访问。


所以破坏互斥条件,从而预防死锁的方法不可行,而且在有的场合应该保护这种互斥性。

②破坏不可剥夺条件:

当一个已经保持了某些不可剥夺资源的进程,若想继续请求新的资源而得不到满足的时候,必须先把已有资源释放,待需要后再重新申请。


这意味着,一个进程已占有的资源会被暂时释放,或者说资源被剥夺了,从而破坏了资源不可剥夺条件。
该策略实现起来较为复杂,释放已经获得的资源可能造成前一阶段工作的失效,反复申请和释放资源会增加系统开销。这种方法常用于状态易于保存和恢复的资源。(如CPU的寄存器资源,一般不能用于打印机之类的资源。)

③破坏占有且申请条件

采用预先静态分配方法。 即:进程在运行前一次性申请完它需要的所有资源,在它的资源未满足前,就不把该进程投入运行。一旦投入运行后,这些资源就归它所有,也不再提出其他资源请求,从而避免了死锁的发生。


这种方式实现简单,但是缺点也显而易见。系统资源浪费严重,有些资源可能在运行结束时才使用、甚至根本不使用,从而导致“饥饿”现象。当由于个别资源长期被其占用,可能导致等等待该资源的进程久久不能开始运行。

④破坏环路等待条件

采用:顺序资源分配法。首先给系统中的资源编号,规定每个进程,必须按编号递增的顺序等待请求资源,同类资源一次 申请完。
也就是说,只要进程提出申请资源Ri,则该进程在以后的资源申请中,只能申请编号大于Ri的资源。


这种方法存在一定的问题:编号必须相对稳定,限制了新类型设备的增加;尽管在为资源编号时已经考虑到大多数进程实际使用这些资源的顺序; 但也会发生进程使用资源的顺序与系统规定的顺序不一致的情况,造成资源的浪费。 (这种按规定次序申请资源的方法,也会给用户的编程带来麻烦)

综上所述:通过以上四种方法防止死锁的发生都不太可行。既然我们无法防止死锁的发生,那是否有方法避免呢?


5. 死锁的避免

避免死锁同样是属于事先预防的策略,但并不是事先采取某种限制措施破坏死锁的必要条件。而是在资源动态分配的过程中, 防止系统进入不安全的状态,以避免发生死锁。 这种方法所施加的限制条件较弱,可以获得较好的系统性能。

①系统安全状态

避免死锁的方法中,允许进程动态地申请资源,但系统在进行资源分配之前,应先计算此次资源分配的安全性。若此次分配不会导致系统进入不安全状态,则将资源分配给进程;否则,让进程等待。


安全状态:系统能按某种进程推进顺序,为每个进程Pi分配其所需资源,直至满足每个进程对系统的最大需求,使每个进程都可顺序地完成。
此时,称:P1,P2,……Pn 为安全序列。 如果系统无法找到一个安全序列,则系统处于不安全的状态。

②银行家算法

思想:
1. 把操作系统看作是银行家,把资源看作是银行的资金,把进程申请资源这一过程看作是用户向银行家贷款。
2. 操作系统按照银行家的规定为进程分配资源,当进程第一次向操作系统申请资源是,需要先检测进程对资源的最大需求量。
3. 当系统现有的资源可以满足进程的最大需求量,则按当前的需求量进行分配,否则推迟分配。
4. 当进程在执行的过程中,再次向系统申请资源,若:“已有资源” 与“申请资源 ”的和超过最大需求量,系统拒绝分配资源。
5. 若未超过最大需求量,但是系统内部现有资源不够满足进程,也会推迟分配。


6. 死锁的检测:

一般来说,由于操作系统具有并发、共享、 随机性等特点,通过预防和避免的方法排除死锁是很困难的。需要较大的系统开销,而且不能充分利用资源。
为此,一种简便的方法是系统为进程分配资源时,不采取任何限制性措施,但是提供了检测和解脱死锁的手段: 能发现死锁并从死锁状态中恢复出来。(这是实际的操作系统往往采用的方法)


什么时候进行死锁的检测?——取决于死锁发生的频率。
如果死锁发生的频率高,那么死锁检测的频率也相应提高,这样一方面可以提高系统资源的利用率,一方面可以避免更多的进程卷入死锁。
如果进程申请资源不能满足就立刻进行检测,那么死锁一经形成就被发现。(这和死锁避免的算法相近,只是系统的开销较大。)
为了减小死锁检测带来的系统开销,一般采取间隔一段时间进行一次死锁检测,或者在CPU的利用率降低到某一数值时,进行死锁的检测。


7. 死锁的恢复

一旦在死锁检测中发现了死锁,就要消除死锁,使系统从死锁状态恢复过来。

① 重新启动系统

这是最简单的方法,但是这种方法代价很大,意味着在这之前所有的进程已经完成的计算工作都已付诸东流,包括参与死锁的进程,以及未参与死锁的进程。

②撤销进程,剥夺资源

终止参与死锁的进程,收回它们的资源,从而解除死锁。分两种情况:
1. 一次性撤销参与死锁的全部进程,剥夺全部资源,从而解除死锁。
**2. 逐步撤销参与死锁的进程,逐步收回死锁进程占有的资源。
撤销的原则可以按进程优先级和撤销进程代价的高低进行)**

③进程回退

让参与死锁的进程回退到没有发生死锁前的某一点,并由此点处继续执行,以求再次执行时不再发生死锁。
虽然这是个比较理想的办法,但是操作起来系统的开销极大,要有堆栈这样的机构记录进程的每一步变化,以便今后的回退,有时这是无法做到的。


三、经典死锁案例——哲学家就餐

https://blog.youkuaiyun.com/zhourong0511/article/details/80266109

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值