基本
在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 以满足您的需要。