我需要一些帮助来实现在多处理过程中进行日志记录以及在Windows下冻结应用程序的运行。关于这个主题有很多主题,我花了很多时间来复习和测试这些主题。我还广泛回顾了the documentation,但是我不知道如何在我的代码中实现这一点。
我创建了一个最小示例,该示例在Linux上运行良好,但在Windows上崩溃(即使未冻结)。我创建的示例只是我将代码放入其中的众多迭代之一。
您可以找到minimum example on github。对于使该示例正常工作的任何帮助,将不胜感激。
谢谢。
马克。
答案 0 :(得分:0)
在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。