一、死锁的定义
运行过程中,多个进程因争夺资源而造成的一种互相等待的僵局。
具体来说,某个任务在等待另一个任务,而后者又等待别的任务,这样一直下去,直到这个链条上的任务又在等待第一个任务释放锁。这导致了一个任务之间相互等待的连续循环,没有哪个线程能继续。这被称之为死锁。
二、构成死锁的必要条件是什么?
死锁产生的四个必要条件:
1、互斥条件:一个资源每次只能被一个进程使用。
2、请求和保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
3、不可剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺。
4、循环条件等待:若干进程之间形成一种头尾相接的循环等待资源关系。
要解决死锁问题,就必须打破上面四个条件的其中之一。在程序中,最容易打破的往往是第四个条件。
三、死锁的处理策略
1、预防死锁:设置某些限制条件,以破坏产生死锁的4个必要条件,以防发生死锁。
(该方法最容易实现,但是副作用就是使系统资源利用率比较低,严重损害系统性能)
2、避免死锁:资源动态分配时,防止系统进入不安全状态(可能产生死锁的状态),以避免发生死锁。
(该方法要求较多的数据结构,实现起来困难,但是资源利用率最高)
3、检测死锁:死锁发生后,采用一定的算法进行检测,确定与死锁相关的资源和进程。
4、解除死锁:对检测到和死锁相关的进程、资源,通过撤销、挂起、进程回退的方式,从而将系统从死锁中解脱出来。
注:使用银行家算法避免死锁
所谓银行家算法,是指在分配资源之前先看清楚,资源分配后是否会导致系统死锁。如果会死锁,则不分配,否则就分配。
四、如何避免死锁?
1、确保所有的线程都是 按照相同的顺序获得锁,那么死锁就不会发生。
2、在尝试获取锁的时候加一个 超时时间,这也就意味着在尝试获取锁的过程中若超过了这个时限该线程则放弃对锁的请求。若一个线程没有在给定的时限内获得所有需要的锁,则会进行回退并释放掉所有已获得的锁,然后等待一段随机的时间再重试。
3、 死锁检测 是一个更好的死锁预防机制,它主要是针对那些不可能实现按序加锁并且锁超时也不可行的场景。
五、如何解除死锁?
1、资源剥夺法:挂起某些死锁进程,并抢占它们的资源,将这些资源分配给其他的死锁进程。
2、撤销进程法:强制撤销部分、甚至全部死锁进程,剥夺这些进程的资源(按进程优先级和撤销进程代价的高低进行)。
3、进程回退法:让一个(多个)进程回退到足以避免死锁的地步。