在Windows上冻结并运行Python的Python多处理返回结果

时间:2020-10-13 13:07:39

标签: python windows logging multiprocessing

我需要一些帮助来实现在多处理过程中进行日志记录以及在Windows下冻结应用程序的运行。关于这个主题有很多主题,我花了很多时间来复习和测试这些主题。我还广泛回顾了the documentation,但是我不知道如何在我的代码中实现这一点。

我创建了一个最小示例,该示例在Linux上运行良好,但在Windows上崩溃(即使未冻结)。我创建的示例只是我将代码放入其中的众多迭代之一。

您可以找到minimum example on github。对于使该示例正常工作的任何帮助,将不胜感激。

谢谢。

马克。

1 个答案:

答案 0 :(得分:0)

基本

在Linux上,默认情况下是通过fork方法创建一个子进程。这意味着子进程几乎继承了父进程的所有内容。

在Windows上,子进程是通过spawn方法创建的。 这意味着,子进程几乎从崩溃开始,重新导入并重新执行保护云if __name__ == '__main__'之外的任何代码。

为什么工作或失败

在Linux上,因为logger对象是继承的,所以程序将开始记录。 但这远非完美,因为您直接登录到文件。 由于进程之间的竞争状况,日志行迟早会重叠,或者在文件上发生IO错误。

在Windows上,由于您没有将logger对象传递给子进程,而是重新导入了pymp_global模块,因此loggerNone对象。因此,当您尝试使用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