知道线程在哪里被阻塞

Know where the thread is blocked

我有一些 python 线程最终永远阻塞等待某些东西,我想 python 告诉我哪个语句阻塞了它们。

我的情况如下:我正在使用一些导致我的线程阻塞的库。我不知道库的代码,所以调试的第一步是让 python 告诉我哪些语句是错误的。

有没有办法让python变成"tell me which threads are blocked now and which statement they are in"?

查看这个简短的示例程序,它使用 faulthandler.dump_tracebackall_threads=True(默认值)

它创建了 6 个线程。 3 会长时间运行,在f1函数中得到"blocked"。其他三个将 运行 f2,在短时间后完成并退出。

import faulthandler
import threading
import time


def f1():
    time.sleep(99999)

def f2():
    i = 1
    for j in range(10000):
        i += 1


for i in range(3):
    threading.Thread(target=f1).start()

for i in range(3):
    threading.Thread(target=f2).start()


time.sleep(1)

faulthandler.dump_traceback()

在 运行 运行此程序后,您会注意到它卡住了(由于打开的线程),但在给出如下输出之前不会:

Thread 0x000040f8 (most recent call first):
  File "stack.py", line 7 in f1
  File "C:\Program Files\Python37\lib\threading.py", line 865 in run
  File "C:\Program Files\Python37\lib\threading.py", line 917 in _bootstrap_inner
  File "C:\Program Files\Python37\lib\threading.py", line 885 in _bootstrap

Thread 0x000034d8 (most recent call first):
  File "stack.py", line 7 in f1
  File "C:\Program Files\Python37\lib\threading.py", line 865 in run
  File "C:\Program Files\Python37\lib\threading.py", line 917 in _bootstrap_inner
  File "C:\Program Files\Python37\lib\threading.py", line 885 in _bootstrap

Thread 0x00003a60 (most recent call first):
  File "stack.py", line 7 in f1
  File "C:\Program Files\Python37\lib\threading.py", line 865 in run
  File "C:\Program Files\Python37\lib\threading.py", line 917 in _bootstrap_inner
  File "C:\Program Files\Python37\lib\threading.py", line 885 in _bootstrap

Current thread 0x00004bb8 (most recent call first):
  File "stack.py", line 24 in <module>

正如我们所见,主线程在第 24 行(触发此消息的 faulthandler.dump_traceback 调用的位置),其他 3 个线程当前在 f1,第7、准确地说是time.sleep(99999)

我们不一定知道它们是 "blocked",事实上我们在检查之前等待了一段合理的时间,在本例中为 1 秒。如果有必要,你也许可以用一个循环反复检查,以监视哪些线程在一段时间后仍然在同一个函数中。