这是一个面试问题。
如何检测并找出程序是否处于死锁状态?在Linux/Unix系统上有哪些工具可以用来做到这一点?
我的想法:
如果一个程序没有进展而且其状态为运行中,那么它就会陷入死锁。但是,其他原因也可能导致这个问题。开源工具valgrind(halgrind)可以做到这一点。对吗?
这是一个面试问题。
如何检测并找出程序是否处于死锁状态?在Linux/Unix系统上有哪些工具可以用来做到这一点?
我的想法:
如果一个程序没有进展而且其状态为运行中,那么它就会陷入死锁。但是,其他原因也可能导致这个问题。开源工具valgrind(halgrind)可以做到这一点。对吗?
ps aux | grep <exe name>
命令,如果输出中的PROCESS STATE CODE
是D
(不可中断睡眠),则表示存在死锁。因为正如@daijo所解释的那样,假设有两个线程T1
和T2
,每个线程都受到S1& S2
信号量保护的两个关键部分,如果T1
获取了S1
并且T2
获取了S2
,然后在放弃已经持有的一个之前,他们尝试获取另一个锁,这将导致死锁,在执行ps aux | grep <exe name>
时,process state code
将是D
(即不可中断睡眠)。
工具:
Valgrind、Lockdep(Linux内核工具)ps aux
的输出D
“可能”意味着进程处于死锁状态,根据此Redhat文档:
不可中断的睡眠状态
不可中断的睡眠状态是指 它不会立即处理信号。只有在等待资源变得可用或者在等待期间超时(如果在将进程置于睡眠状态时指定了超时时间),它才会唤醒。
我建议您查看Helgrind:线程错误检测器。
这种问题的最简单例子如下。
想象一下某个共享资源R,由于某种原因,它由两个锁L1和L2保护,当访问R时必须同时持有这两个锁。
假设一个线程先获取L1,然后获取L2,并继续访问R。这意味着程序中的所有线程都必须按照先L1再L2的顺序获取这两个锁。否则就会出现死锁的风险。
如果两个线程(称为T1和T2)都想访问R,则可能会发生死锁。假设T1首先获取L1,T2首先获取L2。然后T1尝试获取L2,T2尝试获取L1,但这些锁已经被持有。因此,T1和T2将陷入死锁状态。