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 上冻结运行的主要内容,如果未能解决你的问题,请参考以下文章

Python Pandas 多处理无结果返回

如何使用线程去执行一个 有返回值的方法,并获取返回值?

Python多处理:如何创建x个进程并返回返回值

如何使用Python和OpenCV进行多处理?

从 Python 多处理中的排队进程获取错误标志/消息

Python获取多进程执行的返回值