详解Linux死锁概念 死锁的四个必要条件

概述今天主要介绍下死锁的一些原因及条件,银行家算法以及预防的方法 。要想说银行家,首先得说死锁问题,因为银行家算法就是为了死锁避免提出的 。那么,什么是死锁?简单的举个例子:两人吃饺子,一个人手里拿着酱油,一个人手里拿着醋,拿酱油的对拿着醋的人说:“你把醋给我,我就把酱油给你”;拿醋的对拿着酱油的人说:“不,你把酱油给我,我把醋给你 。”
于是,这两个人这两份调料是永远吃不上了 。这就是死锁 。

详解Linux死锁概念 死锁的四个必要条件

文章插图
01死锁的原因和必要条件1.死锁的概念
一般情况下,如果同一个线程先后两次调用lock,在第一次调用时,由于锁已经被占,该线程会挂起等待别的线程释放锁,然而锁正是被自己占着的,该线程又被挂起,没有机会释放锁,因此,就永远处于挂起等待状态了,这叫做死锁(Deadlock) 。另种典型的死锁情形是这样:线程A获 得了锁1,线程B获得了锁2,这时线程A调用lock试图获得锁2,结果是需要挂起等待线程B释放锁2,而这时线程B也调用lock试图获得锁1,结果是需要挂起等待线程A释放锁1,于是线程A和B都永远处于挂起状态了 。
详解Linux死锁概念 死锁的四个必要条件

文章插图
死锁
所谓死锁,是指多个线程在运行过程中因争夺资源而造成的一种僵局(DeadlyEmbreace)即互相等待的现象,当线程处于这种僵持状态时,若无外力作用,它们都将无法向前推进 。
2.产生死锁的原因
(1).竞争资源 。当系统中供多个线程共享的资源如打印机,公用队列等,其数目不足以满足诸线程的需要的时候,会引起诸线程对资源的竞争而产生死锁 。
(2).线程间推进顺序非法 。线程在运行过程中,请求和释放资源的顺序不当,也同样会导致产生线程死锁 。
下面详细分析产生死锁的原因:
(1)竞争资源引起死锁
1)可剥夺性和非剥夺性资源
可把系统的资源分成两类,一类是可剥夺性资源,是指某线程在获得这类资源后,该线程可以再被其它线程或系统剥夺 。如优先级高的线程可以剥夺优先级低的线程的资源 。又如线程间的切换 。另一类是非剥夺性资源,当系统把这类资源分配给某个线程后,再不能强行收回,只能在其用完后自行释放,如磁带机、打印机等 。
2).竞争非剥夺性资源
在系统所配置的非剥夺性资源,由于它们的数量不能满足诸线程的需要,会使线程在运行过程中,因争夺这些资源陷入僵局 。
3).竞争临时性资源
打印机资源属于可顺序重复使用型资源,称为永久性资源 。所谓的临时性资源,是指被线程使用一短暂时间后便无用的资源,故也称之为消耗性资源,它也可能引起死锁 。
(2).线程推进顺序不当引起死锁
如开始所提线程A获 得了锁1,线程B获得了锁2,这时线程A调用lock试图获得锁2,结果是需要挂起等待线程B释放锁2,这时线程B也调用lock试图获得锁1,结果是需要挂起等待线程A释放锁1,于是线程A和B都将永远处于挂起状态了 。
3.产生死锁的必要条件
虽然线程在运行过程中可能发生死锁,但死锁的发生也必须具备一定的条件 。综上所述不难看出,死锁的发生必须具备下列四个必要条件 。
(1).互斥条件:指线程对所分配的资源进行排它性使用,即在一段时间内某资源只由一个线程占用 。如果此时还有其它线程请求该资源,则请求者只能等待,直至占有该资源的线程用毕释放 。
(2).请求和保持条件:指线程已经保持了至少一个资源,但又提出了新的资源请求,而该资源又被其它线程占有,或者已经拥有了该资源却又再次请求,此时请求线程阻塞,但又对自己已获得的资源保持不放 。
(3).不剥夺条件:指线程在已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放 。
(4).环路等待条件:指在发生死锁时,必然存在一个线程--资源的环形链,即线程集合{P0,P1,P2,P3,...Pn}中的P0正在等待P1占用的资源;P1正在等待P2占用的资源,......,Pn正在等待已被P0占用的资源 。
4.处理死锁的基本方法
为保证系统中诸线程的正常运行,应事先采取必要的措施,来预防发生死锁 。在系统中已经出现死锁后,则应及时检测到思索的发生,并应采取适当的措施来解除死锁 。目前,处理死锁的方法可归结为以下四种:
(1).预防死锁 。这是一种较简单和直观的方法 。该方法是通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或几个,来预防发生死锁 。但由于所施加的限制条件往往太严格,因而会导致系统资源利用率和系统吞吐量低 。