Обработчики сигналов и вход в Python - PullRequest
9 голосов
/ 05 января 2011

Документация для модуля протоколирования говорит, что

Если вы реализуете асинхронные обработчики сигналов с помощью сигнального модуля, вы не сможете использовать ведение журнала из таких обработчиков.Это связано с тем, что реализации блокировок в поточном модуле не всегда повторно поступают, и поэтому их нельзя вызывать из таких обработчиков сигналов.

Это говорит о том, что не следует регистрировать вызовы из кода, вызванногообработчик сигнала прямо или косвенно.Если вы делаете это время от времени, программа останется в состоянии, когда помогает только kill -9.

Важным вопросом для меня сейчас является следующий.Может ли эта проблема блокировки возникнуть, когда другие потоки вызывают методы ведения журнала в то время, когда основной поток обрабатывает сигнал ?

Ответы [ 2 ]

8 голосов
/ 05 января 2011

Обработчики сигналов вообще нуждаются в специальной обработке в программировании UNIX.Только определенный список функций POSIX C объявлен как входящий и может быть вызван в обработчике сигналов POSIX.IEEE Std 1003.1 перечисляет 118 реентерабельных функций UNIX, которые вы найдете в https://www.opengroup.org/ (требуется регистрация).

Но сигналы Python асинхронны: сигнальный модуль имеет пояснение:

Хотя обработчики сигналов Python вызываются асинхронно в том, что касается пользователя Python, они могут происходить только между «атомарными» инструкциями интерпретатора Python.Это означает, что сигналы, поступающие во время длинных вычислений, реализованных исключительно на языке C (например, совпадения с регулярными выражениями в больших текстах), могут задерживаться на произвольное время.

В этом случае сигналы в Pythonоткладываются до тех пор, пока GIL не станет бесплатным .

Вернуться к вашему вопросу. Нет , пока вы используете функции повторного входа в функции обработки сигнала.Если ведение журнала используется только в потоках, проблем не будет.

2 голосов
/ 05 января 2011

GIL (Global Interpreter Lock) предотвращает одновременный запуск любого кода Python, поэтому технически основной поток не может обработать сигнал во время работы других потоков. Это может «выглядеть» таким образом, но есть один большой мьютекс, который позволяет запускать одновременно только один поток Python.

Насколько я могу догадаться, проблема с сигналами и потоками заключается в том, что сигнал обычно вызывается прерыванием, которое может произойти в любое время. Так что я представляю, что Python останавливает свою работу и вызывает обработчик. К этому моменту блокировка, возможно, уже была получена, и поэтому, если регистрация попытается заблокировать снова, вы получите тупик. В некоторых реализациях это работает нормально, потому что мьютекс может быть заблокирован несколько раз (повторный вход), но в других есть только одна блокировка.

Надеюсь, кто-то еще сможет это подтвердить.

...