检测活动应用程序中死锁的方法

4
  1. 如何检测一个正在运行的多线程应用程序中的死锁?

  2. 如果我们发现了死锁,是否有任何方法可以解决它,而不需要关闭/重启应用程序?

3个回答

3
有两种常用的方法来检测死锁。
一种是让线程设置检查点。例如,如果您有一个工作循环的线程,在开始工作时设置一个计时器,时间比您认为工作可能需要的时间长。如果计时器触发,则假定线程已死锁。当工作完成时,取消计时器。
另一种(有时与上述方法结合使用)是让线程可能会阻塞的事物跟踪线程可能持有的其他资源。这可以直接检测到在其他线程以相反的顺序获取这些锁时,尝试获取一个锁同时持有另一个锁的情况。
这甚至可以在实际死锁发生之前检测到死锁风险。如果一个线程先获取锁A然后获取锁B,另一个线程则先获取锁B然后获取锁A,除非它们重叠,否则不会出现死锁。但是这种方法可以检测到它。
高级死锁检测通常仅在调试期间使用。除了编写应用程序以检查每个阻塞锁是否可能死锁并知道如何处理它,死锁发生后唯一能做的就是拆除应用程序。您不能盲目释放锁,因为它们保护的资源可能处于不一致状态。
有时,您会故意编写可能死锁的代码,并将其编码以避免该问题。例如,如果您知道许多线程获取锁A然后尝试获取锁B,而某些其他线程需要执行相反操作,则可以编写一个非阻塞尝试锁定B并在失败时释放锁A的代码。
通常,花费精力使死锁不可能比使代码检测和解决死锁更有用。

Java线程转储能用于检测死锁吗?它可以告诉我们哪些线程被阻塞,但不确定是否能检测到死锁。 - Amber Beriwal
1
@AmberBeriwal 这个方法可行。通过获取所有线程堆栈的转储,您可以尝试找出哪个线程正在尝试获取锁并被阻塞,以及哪个线程持有该锁。如果您有很多线程,这可能会很繁琐,但并非不可能。 - David Schwartz

0
在Python中,有一个名为locklib的库可以实现这个功能。它提供了一个互斥类,可以防止死锁的发生。如果你尝试获取一个会导致互斥锁的锁,那么在尝试这样做的线程中会引发一个异常。这个实现是基于Wait-For Graph的。

0

Python有一个名为faulthandler的特性,非常适用于处理死锁问题:

import faulthandler
faulthandler.register(signal.SIGUSR1)

如果您正在使用C++或任何使用glibc的编译器,您可以使用execinfo.h中的backtrace()函数打印堆栈跟踪并在收到信号时优雅地退出。您可以获取死锁程序,向其发送信号并获取所有线程的列表。
在Java中,对于被卡住的进程,请使用jstack <pid>

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