Python多进程日志记录,Windows中的根记录器不同。

7

我尝试使用多进程进行日志记录,发现在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 位系统下,主函数和功能函数之间的根记录器将会不同:

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

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

1个回答

5
我认为这可能与以下平台相关行为有关:

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

(...)

全局变量

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

但是,仅是模块级常量的全局变量不会引起问题。

根据您的问题,我猜测这导致了一个未能到达所有进程的logging.basicConfig()调用。解决方法是将您的子进程记录到一个Queue(使用QueueHandler),并在主进程中拥有一个专用线程来监听队列。

谢谢,我认为这真的是原因,我看到了另一个类似的答案https://dev59.com/0m3Xa4cB1Zd3GeqPkfFZ#14643726。顺便说一下,似乎`QueueHandler`只存在于Python 3.x中。 - Tanky Woo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接