我在生产中运行了一个Python守护程序。它使用7到120个线程。最近,最小的实例(7个线程)开始显示挂起,而所有其他实例从未显示过这种问题。将strace附加到python进程显示所有线程都在调用futex FUTEX_WAIT_PRIVATE,因此他们可能正在尝试锁定某些内容。
你会如何调试这样的问题?
请注意,这是一个从闪存运行的生产系统,因此磁盘写入也受到限制。
答案 0 :(得分:4)
观察结果略显不正确。一个线程没有调用futex,而是在持有gil的同时进行交换。由于所讨论的机器硬件很低,这种交换耗时很长,似乎是一个僵局。潜在的问题是内存泄漏。 : - (
答案 1 :(得分:1)
亲爱的赫尔穆特,我在FUTEXT_WAIT_PRIVATE上悬挂一个主题也遇到了同样的问题。
看来你已经解决了这个问题。您能分享一下有关该解决方案的更多信息吗?
UPD:
终于发现了锁定的原因(至少在我的情况下):这是由于Python中的导入锁定。
考虑以下情况:
file1.py:
导入文件2
file2.py:
创建线程“thread2”
运行“thread2”
等到“thread2”完成一些功能(让我们说去Go())
def Go():
导入some_module
...
这里Go()中的导入会挂起,因为导入被锁定在主线程中(通过import file2),在Go()完成之前不会释放。用户将在FUTEX_WAIT_PRIVATE看到strace挂起。
要解决此处将file2导入Do()函数期间执行的代码,并在导入file2后运行它:
导入文件2
file2.Do()