Python挂起在futex调用中
我有一个Python守护进程正在生产环境中运行。它使用7到120个线程。最近,最小的实例(7个线程)开始显示挂起,而所有其他实例从未显示此类问题。将strace附加到python进程表明所有线程都在调用futex futex_WAIT_PRIVATE,因此它们可能试图锁定某些内容 您将如何调试这样的问题Python挂起在futex调用中,python,multithreading,debugging,deadlock,futex,Python,Multithreading,Debugging,Deadlock,Futex,我有一个Python守护进程正在生产环境中运行。它使用7到120个线程。最近,最小的实例(7个线程)开始显示挂起,而所有其他实例从未显示此类问题。将strace附加到python进程表明所有线程都在调用futex futex_WAIT_PRIVATE,因此它们可能试图锁定某些内容 您将如何调试这样的问题 请注意,这是一个使用闪存运行的生产系统,因此磁盘写入也受到限制。观察结果有点不正确。一个线程没有调用futex,而是在持有gil时交换。由于所讨论的机器是低硬件,所以这种交换花费了很长时间,似乎
请注意,这是一个使用闪存运行的生产系统,因此磁盘写入也受到限制。观察结果有点不正确。一个线程没有调用futex,而是在持有gil时交换。由于所讨论的机器是低硬件,所以这种交换花费了很长时间,似乎是一种死锁。根本问题是内存泄漏:-(亲爱的Helmut,我有一个线程挂在FUTEXT\u WAIT\u PRIVATE上的问题 看来你已经解决了这个问题。你能分享更多关于这个解决方案的信息吗 UPD: 最终找到了锁的原因(至少对我来说是这样):这是由于在Python中导入了锁 考虑以下情况: file1.py: 导入文件2 file2.py: 创建线程“thread2” 运行“thread2” 等待“thread2”完成某个函数(比如go()) def Go(): 导入一些模块 在这里,Go()中的导入将挂起,因为导入被锁定在主线程中(通过导入文件2),直到Go()完成后才会释放。用户将在FUTEX\u WAIT\u PRIVATE上的strace挂起中看到 要解决此问题,请放置在将file2导入Do()函数期间执行的代码,并在导入file2后运行该代码: 导入文件2 file2.Do()
今天,我观察到除了控制台线程外,所有线程中都挂着同一个实例。它正在执行select(1,[0],…)。当我键入一行时,它也在与所有其他线程相同的futex调用中死锁(除了一个线程,它使用不同的地址)。与此同时,全局导入锁最终在CPython 3.3中被替换,请参见。这对我来说是个好消息……我在10年前就已经发现了这一点——今天又是如此——每次,我都花了一天多的时间来理解正在发生的事情……请注意,Python文档中不鼓励从线程导入模块。你是对的。一个好主意是在第一行代码中导入所有需要的模块,但不幸的是,这在大型项目中是不可能的。在我的项目中,我更喜欢将这些导入保留在代码中正确的位置,以保持可读性,并遵守一个简单的规则:首先导入,然后运行新线程。对于我的大型项目来说效果很好。