【问题标题】:Python Multiprocessing returning results with Logging and running frozen on WindowsPython 多处理返回结果,记录并在 Windows 上冻结运行
【发布时间】:2021-01-27 20:01:42
【问题描述】:

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

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

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

谢谢。

马克。

【问题讨论】:

    标签: python windows logging multiprocessing


    【解决方案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
    猜你喜欢
    • 1970-01-01
    • 2021-09-30
    • 2014-08-25
    • 1970-01-01
    • 1970-01-01
    • 2017-10-16
    • 1970-01-01
    • 2015-01-18
    • 1970-01-01
    相关资源
    最近更新 更多