线程死锁
在支持多线程的操作系统中,线程死锁是指多个线程因相互等待资源而导致的死锁状态。线程死锁可以分为两种类型:
- 同一进程的线程死锁
- 在同一个进程中,不同线程可能会因为共享同一进程的资源(如变量、内存等)而发生死锁。为了同步访问这些资源,线程通常使用互斥锁(mutex)来进行互斥操作。
-
死锁发生场景:
- 设有两个互斥锁:
L1和L2。 - 线程
T1获得了L1,并请求L2; - 线程
T2获得了L2,并请求L1。 - 由于两个线程相互等待对方释放锁,造成死锁,两个线程无法继续执行。
- 设有两个互斥锁:
-
死锁原因:线程在持有一个锁的同时请求另一个锁,而该锁被另一个线程持有。这种循环等待的情况导致死锁。
-
不同进程的线程死锁
-
不同进程的线程死锁是指两个或更多进程中的线程发生相互等待,无法继续执行。假设有两个进程
P1和P2,每个进程内有多个线程:- 进程
P1中的线程P11、P12、...,进程P2中的线程P21、P22、...; - 进程
P1的线程P11获得了资源R1,进程P2的线程P21获得了资源R2; - 如果
P11请求R2但无法获得,进入阻塞状态,等待P21释放R2; - 同时,
P21请求R1但无法获得,进入阻塞状态,等待P11释放R1; - 这时,
P11和P21相互等待对方释放资源,导致死锁。
- 进程
-
死锁原因:进程间的线程相互持有对方需要的资源,并且在等待中形成循环等待。
解决方案
线程死锁的解决方法基本与进程死锁的解决方法类似,可以通过以下方式处理:
- 死锁预防:通过限制资源的申请顺序或设计资源分配规则,防止死锁的发生。
-
如:使用资源排序策略,要求线程按固定顺序申请资源,避免形成循环等待。
-
死锁避免:通过动态检查线程的资源请求,确保在资源分配后系统处于安全状态,从而避免死锁。比如使用银行家算法来避免死锁。
-
死锁检测与解除:允许系统发生死锁,但定期运行死锁检测程序,识别死锁并采取措施解决。例如:
- 终止进程:结束某个死锁进程,释放资源。
- 回滚进程:回退某个进程到之前的安全状态,释放资源。
总结
- 同一进程的线程死锁:线程因互斥锁的申请顺序错误或竞争导致死锁。
- 不同进程的线程死锁:不同进程中的线程因相互等待资源而发生死锁。