У меня проблема при использовании модуля 'logging' вместе с модулем 'multiprocessing'.Разветвленный дочерний элемент заканчивается блокировкой и зависает при любой попытке журнала.
Регистратор использует StreamHandler для sys.stdout и sys.stderr и SysLogHandler (который, по-видимому, несет активную блокировку от своего родителя).
Схема выглядит следующим образом:
- рабочие процессы реализованы в виде потоков (Thread)
- рабочие задания, выполняемые рабочими, являются подпроцессами (Process)
Я продолжаю получать блокировки в разных местах, таких как: logging._lock, SysLogHandler.lock, в зависимости от моих попыток санации модуля.
В общем, я не люблю взаимодействовать с модулями за пределами их API, но в этом случае я смело пытался:
cur_logger = logging.getLogger()
cur_logger.handlers = []
logging._lock = RLock()
logging._handlerList = []
logging._handlers = {}
logging.Logger.manager.loggingDict = {}
Со следующим результатом (все еще блокировка):
#0 0x00007fc87bceba00 in sem_wait () from /lib64/libpthread.so.0
#1 0x00007fc87bff8428 in PyThread_acquire_lock (lock=0x921970, waitflag=1) at Python/thread_pthread.h:349
#2 0x00007fc87bffc314 in lock_PyThread_acquire_lock (self=0x7fc87c3ce120, args=<value optimized out>) at Modules/threadmodule.c:47
#3 0x00007fc87bfd09d4 in call_function (f=<value optimized out>, throwflag=<value optimized out>) at Python/ceval.c:3794
#4 PyEval_EvalFrameEx (f=<value optimized out>, throwflag=<value optimized out>) at Python/ceval.c:2453
#5 0x00007fc87bfd2647 in PyEval_EvalCodeEx (co=0x7fc87c3f1828, globals=<value optimized out>, locals=<value optimized out>, args=<value optimized out>, argcount=1, kws=0x7fc85c003fd0, kwcount=0, defs=0x7fc87c3666e8, defcount=1, closure=0x0) at Python/ceval.c:3044
Я использую довольно старые пакеты, поэтому мой вопрос, является ли этоизвестная ошибка исправлена позже, или есть способ как-то санировать модуль журналирования на fork, чтобы он очистил все блокировки (AFAIK это не системные блокировки и они не имеют отношения к разветвлению после fork), или, возможно, я что-то делаю неправильно.
Спасибо,
Версии:
- python: python-2.6.6-66.el6_8.x86_64
- logging. версия : 0.5.0.5
- многопроцессорная. версия : 0.70a1
Edit_1:
Я провел такой же тест на CentOS 7, который имеет лучший вывод отладчика для python, и зависает из-за SysLogHandler.lock (_RLock__count = 1):
- Должен ли я сосредоточиться на отслеживании экземпляра SyLogHandler, который был перенесен в дочерний элемент
- , или есть другая запись в журнал, подходящая для «многопроцессорной обработки»
- или блокировка вызвана каким-либомой код
Отладка:
#0 0x00007f4fa0e7b89c in __lll_lock_wait_private () from /lib64/libc.so.6
#1 0x00007f4fa0e94fad in _L_lock_774 () from /lib64/libc.so.6
#2 0x00007f4fa0e94d65 in __check_pf () from /lib64/libc.so.6
#3 0x00007f4fa0e56fd9 in getaddrinfo () from /lib64/libc.so.6
#4 0x00007f4f98b85c92 in setipaddr (name=<optimized out>, addr_ret=addr_ret@entry=0x7f4f82ff9cf0, addr_ret_size=addr_ret_size@entry=16, af=af@entry=2)
at /usr/src/debug/Python-2.7.5/Modules/socketmodule.c:921
#5 0x00007f4f98b8781e in getsockaddrarg (s=s@entry=0x7f4f896aadb0, args=<optimized out>, addr_ret=addr_ret@entry=0x7f4f82ff9cf0, len_ret=len_ret@entry=0x7f4f82ff9c80)
at /usr/src/debug/Python-2.7.5/Modules/socketmodule.c:1321
#6 0x00007f4f98b87c63 in sock_sendto (s=0x7f4f896aadb0,
args=('<159>Jun 11 14:55:08 xdc.py.Distribute file as xdcrm.139979476948736: DEBUG [16722.139979476948736] _put:Timing SFTP stat+put of /tmp/blob.1M.bin.tmp to 10.67.145.141:/tmp/blob.1M.bin.tmp finished:True size:1048576 time:timer: 0.0349\x00', ('localhost', 514))) at /usr/src/debug/Python-2.7.5/Modules/socketmodule.c:2936
#7 0x00007f4fa1b45cf0 in call_function (oparg=<optimized out>, pp_stack=0x7f4f82ff9ea0) at /usr/src/debug/Python-2.7.5/Python/ceval.c:4408
#8 PyEval_EvalFrameEx (
f=f@entry=Frame 0x7f4f824d5a00, for file /usr/lib64/python2.7/logging/handlers.py, line 863, in emit (self=<SysLogHandler(socket=<_socketobject at remote 0x7f4f8900e980>, level=0, lock=<_RLock(_Verbose__verbose=False, _RLock__owner=139979476948736, _RLock__block=<thread.lock at remote 0x7f4fa1fd4210>, _RLock__count=1) at remote 0x7f4f887bf2d0>,