Python 多处理返回结果,记录并在 Windows 上冻结运行
Posted
技术标签:
【中文标题】Python 多处理返回结果,记录并在 Windows 上冻结运行【英文标题】:Python Multiprocessing returning results with Logging and running frozen on Windows 【发布时间】:2021-01-27 20:01:42 【问题描述】:我需要一些帮助来实现多处理时的日志记录以及在 Windows 下运行冻结的应用程序。关于这个主题有几十个主题,我花了很多时间审查和测试这些主题。我还广泛审查了the documentation,但我不知道如何在我的代码中实现这一点。
我创建了一个在 Linux 上运行良好但在 Windows 上崩溃(即使未冻结)的最小示例。我创建的示例只是我编写代码的众多迭代之一。
您可以找到minimum example on github。任何帮助使此示例正常工作将不胜感激。
谢谢。
马克。
【问题讨论】:
【参考方案1】:基本
在Linux上,默认通过fork
方法创建一个子进程。这意味着,子进程几乎继承了父进程的所有内容。
在 Windows 上,子进程由spawn
方法创建。
这意味着,一个子进程几乎从崩溃开始,重新导入并重新执行保护云if __name__ == '__main__'
之外的任何代码。
为什么成功或失败
在 Linux 上,因为 logger
对象被继承,您的程序将开始记录。
但它远非完美,因为您直接登录到文件。
由于进程之间的竞争条件,日志行迟早会重叠或IO
文件上的错误发生。
在 Windows 上,由于您没有将 logger
对象传递给子进程,并且它重新导入了您的 pymp_global
模块,所以 logger
是一个 None
对象。因此,当您尝试使用 None
对象进行日志记录时,它肯定会崩溃。
解决方案
使用多处理进行日志记录并非易事。
要使其在 Windows 上运行,您必须将记录器对象传递给子进程和/或使用 QueueHandler
记录。另一个类似的进程间通信解决方案是使用SocketHandler
。
这个想法是只有一个线程或进程进行日志记录。其他进程只是发送日志记录。这可以防止竞争条件,并确保在关键进程有时间完成其工作后写出日志。
那么如何实现呢? 我之前遇到过这个日志记录问题,并且已经编写了代码。 您可以将它与logger-tt 包一起使用。
#pymp.py
from logging import getLogger
from logger_tt import setup_logging
setup_logging(use_multiprocessing=True)
logger = getLogger(__name__)
# other code below
对于其他模块
#pymp_common.py
from logging import getLogger
logger = getLogger(__name__)
# other code below
这使您不必在任何地方手动编写所有日志记录配置代码。
您可以考虑更改 log_config
file 以满足您的需要。
【讨论】:
非常感谢您的回答。我正忙着测试。一旦我测试了所有东西,我会回来告诉你进展如何。 这太棒了!我一直在玩 logger-tt 并对其进行了广泛的测试。我当然可以推荐这个包! @Marc 谢谢。如果这个答案有帮助,您可以将其标记为accepted
。以上是关于Python 多处理返回结果,记录并在 Windows 上冻结运行的主要内容,如果未能解决你的问题,请参考以下文章