死锁
死锁是指在并发系统中,两个或多个进程因为互相等待对方释放资源而无法继续执行的状态。
死锁发生的条件通常包括以下四个条件:
- 互斥条件(Mutual Exclusion):
至少有一个资源
被标记为只能被一个进程
占用,即一次只能有一个进程使用该资源。 - 请求与保持条件(Hold and Wait):一个进程在
持有至少一个资源
的同时,又请求其他进程
占用的资源。 - 不可剥夺条件(No Preemption):已经分配给一个进程的资源
不能被强制性地剥夺
,只能由持有该资源的进程主动释放 - 循环等待条件(Circular Wait):存在一个进程资源的循环链,每个进程都在等待下一个进程所占用的资源。
当这四个条件同时满足时,就可能发生死锁。为了避免死锁的发生,可以采取一些策略,如资源预分配、避免循环等待、引入资源剥夺等。
如何应对死锁
死锁预防
前面我们提到,产生死锁的四个必要条件是:互斥条件、持有并等待条件、不可剥夺条件、环路等待条件。
那么避免死锁问题就只需要破环其中一个条件就可以,最常见的并且可行的就是使用资源有序分配法,来破环环路等待条件。
那什么是资源有序分配法呢?
线程 A 和 线程 B 获取资源的顺序要一样,当线程 A 是先尝试获取资源 A,然后尝试获取资源 B 的时候,线程 B 同样也是先尝试获取资源 A,然后尝试获取资源 B。也就是说,线程 A 和 线程 B 总是以相同的顺序申请自己想要的资源。
我们使用资源有序分配法的方式来修改前面发生死锁的代码,我们可以不改动线程 A 的代码。
我们先要清楚线程 A 获取资源的顺序,它是先获取互斥锁 A,然后获取互斥锁 B。
所以我们只需将线程 B 改成以相同顺序的获取资源,就可以打破死锁了。