前言
本文将简要介绍多线程中非常重要的死锁概念,将介绍死锁出现的场景以及解决办法。
一、死锁的概念定义
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
二、死锁产生的四个必要条件
1)互斥条件
指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。
案例理解:比方说现在有一个只能容纳一人乘坐的小船,每次只能载一个人,如果现在船上已经有一个人了,另外一个人请求使用小船就必须等待上一个人下来,结束对小船的使用才行。
2)不剥夺条件
指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
案例辅助理解:案例同上,如果一个人正在小船上,其他人不能将他赶下船,也不能自己也上船,只能等待前一个人使用完下船后留出空位供新人使用。
3)请求和保持条件
指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
案例理解:这个可以用后面将讲到的哲学家用餐的问题做案例解释。哲学家用餐案例指的是假设现在有5为哲学家围坐在圆桌前想要就餐,每人左手边都放置了一根筷子,具体情形如下图:现在观察可以发现,每一名哲学家左右两侧各有一双筷子,但当要求每一名哲学家先拿起自己左侧的筷子时,桌子上的所有筷子资源都被占有了,此时再要求每一名哲学家拿起右侧的筷子时就会出现请求和保持条件,每个人保持自己所拥有的同时请求别人所拥有的,就会造成阻塞,每个人都无法顺利进餐。
4)环路等待条件
指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。
案例辅助理解:这个也可以用哲学家就餐问题来理解,就是上面所说的,所有哲学家都拿取自己左侧的筷子,再申请自己右侧的筷子时就会出现这种环路等待条件。
三、解决办法
1)预防
可以通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或者几个,来预防发生死锁。预防死锁是一种较易实现的方法,已被广泛使用。但是由于所施加的限制条件往往太严格,可能会导致系统资源利用率和系统吞吐量降低。
2)死锁避免
系统对进程发出的每一个系统能够满足的资源申请进行动态检查,并根据检查结果决定是否分配资源;如果分配后系统可能发生死锁,则不予分配,否则予以分配。这是一种保证系统不进入死锁状态的动态策略。
3)死锁检测和解除
先检测:这种方法并不须事先采取任何限制性措施,也不必检查系统是否已经进入不安全区,此方法允许系统在运行过程中发生死锁。但可通过系统所设置的检测机构,及时地检测出死锁的发生,并精确地确定与死锁有关的进程和资源。检测方法包括定时检测、效率低时检测、进程等待时检测等。
然后解除死锁:采取适当措施,从系统中将已发生的死锁清除掉。
这是与检测死锁相配套的一种措施。当检测到系统中已发生死锁时,须将进程从死锁状态中解脱出来。常用的实施方法是撤销或挂起一些进程,以便回收一些资源,再将这些资源分配给已处于阻塞状态的进程,使之转为就绪状态,以继续运行。死锁的检测和解除措施,有可能使系统获得较好的资源利用率和吞吐量,但在实现上难度也最大。
总结
简要介绍的死锁的概念,出现的四个必要条件以及解决方法。