0

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

似乎每次只有一个线程挂起,所以我不太明白为什么它会挂起整个程序。就在那时,我发现了 Stack Overflow 解决方案,它解释说:“在某些 Python 实现中,一次只能执行一个 Python 线程。CPython 中的线程仅对多路复用 IO 操作真正有用,而不是将 CPU 密集型任务置于后台。 " 因此,当一个线程因 CPU 使用率满而挂起时,整个程序就会停止,这是可以理解的。

下面是进程资源管理器在程序挂起时查看 python.exe 进程的屏幕截图。如您所见,实际上只有一个线程在做某事。

流程管理器屏幕截图

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

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

4

2 回答 2

1

这可能有助于 src https://softwareengineering.stackexchange.com/questions/126940/debug-multiprocessing-in-python

import multiprocessing, logging
logger = multiprocessing.log_to_stderr()
logger.setLevel(multiprocessing.SUBDEBUG)
于 2013-06-03T21:20:59.573 回答
0

您可以尝试 Sys Internals 中的 procmon 来查看您的进程在系统调用级别正在/正在做什么。

您还可以尝试使用调试器进行附加,并查看有关为每个线程获取回溯的信息。我不确定 gdb 在 Windows 上的效果如何,但这是我过去在 *ix 上使用的。即使您附加到 C 程序(cpython 解释器),有时您也可以看到 Python 调用堆栈,使用类似http://svn.python.org/projects/python/trunk/Misc/gdbinit的东西

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

于 2013-06-03T22:56:27.410 回答