调试随机挂起并使用100%处理器内核的Python脚本

调试随机挂起并使用100%处理器内核的Python脚本,python,multithreading,debugging,Python,Multithreading,Debugging,我目前正在编写一个相当复杂的多线程Python脚本。有一个主函数一次在大约5个线程中运行。我一直有一些问题,它挂起和使用100%的处理器核心,它是运行。这种挂起是在主函数运行数百次之后发生的,因此很难准确地确定挂起发生的时间或地点。一旦程序挂起,它就再也不会开始运行 似乎一次只有一个线程挂起,所以我真的不明白为什么它挂起整个程序。这就是我发现的解释:“在一些Python实现中,一次只能执行一个Python线程。CPython中的线程只对多路IO操作有用,而不是将CPU密集型任务放在后台。”因此,

我目前正在编写一个相当复杂的多线程Python脚本。有一个主函数一次在大约5个线程中运行。我一直有一些问题,它挂起和使用100%的处理器核心,它是运行。这种挂起是在主函数运行数百次之后发生的,因此很难准确地确定挂起发生的时间或地点。一旦程序挂起,它就再也不会开始运行

似乎一次只有一个线程挂起,所以我真的不明白为什么它挂起整个程序。这就是我发现的解释:“在一些Python实现中,一次只能执行一个Python线程。CPython中的线程只对多路IO操作有用,而不是将CPU密集型任务放在后台。”因此,当一个线程挂起而CPU使用率满时,整个程序就会停止,这是可以理解的

下面是程序挂起时Process Explorer查看python.exe进程的屏幕截图。正如您所看到的,只有一个线程在实际执行某些操作

我希望能够准确地分析脚本挂起之前执行了哪些行。我真的不知道在哪里可以使用“import pdb;pdb.set_trace()”插入断点,因为我不知道何时何地会出错。我无法手动执行该程序,因为它需要运行30分钟到几个小时才能挂起。我试着浏览我的脚本,以找到任何明显的无限循环,可能会导致或类似的结果,但我似乎无法找出导致挂起的原因

我的问题是:我将如何调试它?理想情况下,我只希望看到挂起之前执行了哪些行,但我甚至不知道如何检测挂起的时间。我不能在这里发布完整的脚本,所以希望有人知道我如何调试它。提前谢谢。

这可能会对src有所帮助


您可以从Sys内部尝试procmon,以查看您的进程在系统调用级别正在做什么

您还可以尝试附加一个调试器,看看如何为每个线程获取回溯。我不确定gdb在Windows上的工作情况如何,但这就是我过去在*ix上使用的方法。有时,即使您连接到C程序(cpython解释器),也可以看到Python调用堆栈,使用类似


pdb可能是一个比gdb更好的选择,但我没有为此使用pdb。

还有一本好书,其中一条建议是Python中的线程只能在原子操作上阻塞整个程序,例如,如果您正在对一个非常大的列表进行排序。请使用跟踪模块。您是否尝试发出
键盘中断信号,并查看回溯的来源?@Marcin,这看起来很有趣。我试试看是否有用。谢谢我不确定这是否与我的脚本相关,因为我使用的是线程模块,而不是多处理。在python中,特别是在windows下,多线程没有实现,至少不像在其他语言中那样,我自己还没有看到工作示例,谁知道呢,但也许你所有痛苦的原因是在多线程和多处理之间做出选择
import multiprocessing, logging
logger = multiprocessing.log_to_stderr()
logger.setLevel(multiprocessing.SUBDEBUG)