Регистрация в Python с многопроцессорностью, разные возможности входа в систему

Я попытался войти в систему с многопроцессорностью, и нашел под окнами, я получу другой корневой логгер в дочернем процессе, но под 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-битная, я получу различный root logger между main и func:

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

И если я инициализирую корневой логгер в основных сценариях, как я могу сохранить настройки, такие как уровень дочернего процесса, под окнами?

1 ответ

Решение

Мне кажется, что это может быть связано со следующим зависимым от платформы поведением:

16.6.3.2. Windows Поскольку в Windows отсутствует os.fork(), у нее есть несколько дополнительных ограничений:

(...)

Глобальные переменные

Имейте в виду, что если код, запущенный в дочернем процессе, пытается получить доступ к глобальной переменной, то значение, которое он видит (если он есть), может не совпадать со значением в родительском процессе во время вызова Process.start.

Однако глобальные переменные, которые являются только константами уровня модуля, не вызывают проблем.

Исходя из вашего вопроса, я предполагаю, что это приводит к logging.basicConfig() вызов, который не достигает всех ваших процессов. Решение этой проблемы состоит в том, чтобы ваши дочерние процессы регистрировались в Queue (с помощью QueueHandler) и иметь выделенный поток в вашем основном процессе, который будет прослушивать очередь.

Другие вопросы по тегам