如何检测和发现程序是否陷入死锁?

9

这是一个面试问题。

如何检测并找出程序是否处于死锁状态?在Linux/Unix系统上有哪些工具可以用来做到这一点?

我的想法:

如果一个程序没有进展而且其状态为运行中,那么它就会陷入死锁。但是,其他原因也可能导致这个问题。开源工具valgrind(halgrind)可以做到这一点。对吗?

2个回答

11
如果您怀疑出现死锁,请执行ps aux | grep <exe name>命令,如果输出中的PROCESS STATE CODED(不可中断睡眠),则表示存在死锁。因为正如@daijo所解释的那样,假设有两个线程T1T2,每个线程都受到S1& S2信号量保护的两个关键部分,如果T1获取了S1并且T2获取了S2,然后在放弃已经持有的一个之前,他们尝试获取另一个锁,这将导致死锁,在执行ps aux | grep <exe name>时,process state code将是D(即不可中断睡眠)。 工具: Valgrind、Lockdep(Linux内核工具)
查看此链接,了解死锁类型及其避免方法: http://cmdlinelinux.blogspot.com/2014/01/linux-kernel-deadlocks-and-how-to-avoid.html 编辑:ps aux的输出D“可能”意味着进程处于死锁状态,根据此Redhat文档

不可中断的睡眠状态
不可中断的睡眠状态是指 它不会立即处理信号。只有在等待资源变得可用或者在等待期间超时(如果在将进程置于睡眠状态时指定了超时时间),它才会唤醒。


7
不可中断的睡眠指等待任何数量的资源,通常是IO - 如何将其用于死锁? - excalibur
1
@brokenfoot - 我同意@excalibur的观点,提供的链接中说,该进程“可能”会陷入死锁状态。 - Guy Avraham

5

我建议您查看Helgrind:线程错误检测器

这种问题的最简单例子如下。

想象一下某个共享资源R,由于某种原因,它由两个锁L1和L2保护,当访问R时必须同时持有这两个锁。

假设一个线程先获取L1,然后获取L2,并继续访问R。这意味着程序中的所有线程都必须按照先L1再L2的顺序获取这两个锁。否则就会出现死锁的风险。

如果两个线程(称为T1和T2)都想访问R,则可能会发生死锁。假设T1首先获取L1,T2首先获取L2。然后T1尝试获取L2,T2尝试获取L1,但这些锁已经被持有。因此,T1和T2将陷入死锁状态。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接