python 使用多处理进行日志记录,root 记录器在 windows 中有所不同

python logging with multiprocessing, root logger different in windows

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

测试代码:

main.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()

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

下Linux,结果为:

in main:  <logging.RootLogger object at 0x10e4d6d90>
in func:  <logging.RootLogger object at 0x10e4d6d90>

但在 Windows 7 64 位下,我将在 main 和 func 之间获得不同的根记录器:

in main:  <logging.RootLogger object at 0x00000000021FFD68>
in func:  <logging.RootLogger object at 0x00000000023BC898>

如果我在主脚本中初始化 root 记录器,我怎样才能在 windows 下保留子进程中的级别等设置?

在我看来,这可能与 the following platform-dependant behaviour:

16.6.3.2. Windows Since Windows lacks os.fork() it has a few extra restrictions:

(...)

Global variables

Bear in mind that if code run in a child process tries to access a global variable, then the value it sees (if any) may not be the same as the value in the parent process at the time that Process.start was called.

However, global variables which are just module level constants cause no problems.

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