python 多处理日志记录,根记录器在 Windows 中不同

Tan*_*Woo 5 python windows logging multiprocessing

我尝试使用多处理进行日志记录,发现在 Windows 下,我会在子进程中获得不同的根记录器,但在 Linux 下没问题。

测试代码:

主要.py:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
import multiprocessing
from mymod import func

def m_func():
    server = multiprocessing.Process(target=func, args=())
    server.start()

logger = logging.getLogger()
#print 'in global main: ', logger

if __name__ == '__main__':
    print 'in main: ', logger
    m_func()
Run Code Online (Sandbox Code Playgroud)

mymod.py:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging

logger = logging.getLogger()
# print 'in global func: ', logger

def func():
    print 'in func: ', logger
Run Code Online (Sandbox Code Playgroud)

在Linux下,结果是:

in main:  <logging.RootLogger object at 0x10e4d6d90>
in func:  <logging.RootLogger object at 0x10e4d6d90>
Run Code Online (Sandbox Code Playgroud)

但是在 Windows 7、64 位下,我会在 main 和 func 之间得到不同的根记录器:

in main:  <logging.RootLogger object at 0x00000000021FFD68>
in func:  <logging.RootLogger object at 0x00000000023BC898>
Run Code Online (Sandbox Code Playgroud)

如果我在主脚本中初始化根记录器,如何在 Windows 下的子进程中保留诸如级别之类的设置?

Joë*_*oël 5

在我看来,这可能与以下依赖于平台的行为有关:

16.6.3.2。Windows 由于 Windows 缺少 os.fork() 它有一些额外的限制:

(...)

全局变量

请记住,如果在子进程中运行的代码尝试访问全局变量,那么它看到的值(如果有)可能与调用 Process.start 时父进程中的值不同。

然而,作为模块级常量的全局变量不会引起任何问题。

根据您的问题,我认为这会导致logging.basicConfig()调用未到达您的所有进程。解决方案是让您的子进程登录到Queue(使用QueueHandler),并在主进程中有一个专用线程来侦听队列。