Почему делает поточную обработку использования. Результат события в SIGTERM, не будучи пойманным?

У меня есть потоковый демон Python. Как любой хороший демон, это хочет запустить все свои рабочие потоки, затем ожидать вокруг, пока этому не говорят завершиться. Нормальный сигнал для завершения SIGTERM, и на большинстве языков я держал бы для завершения путем ожидания на событии или взаимном исключении, таким образом с помощью threading.Event имевший смысл мне. Проблема состоит в том что Python Event объект и сигналы Unix, кажется, не играют хорошо вместе.

Это работает как ожидалось, завершаясь на SIGTERM:

import signal
import time

RUN = True

def handle(a, b):
    global RUN
    print "handled"
    RUN = False

signal.signal(signal.SIGTERM, handle)
while RUN:
    time.sleep(0.250)
print "Stopping"

но это приводит к нет SIGTERM будучи поставленным (т.е. вполне кроме выхода, "обрабатываемого" никогда, не печатается):

import signal
import threading

RUN_EVENT = threading.Event()

def handle(a, b):
    print "handled"
    RUN_EVENT.set()

signal.signal(signal.SIGTERM, handle)
RUN_EVENT.wait()
print "Stopping"

Таким образом, мой вопрос:

  1. Я неправильно использую threading.Event в некотором роде?
  2. Если я не, там альтернатива кроме механизма опроса-и-сна от первого примера?
  3. Также, если я не, почему делает использование threading.Event уничтожить обработчик сигналов?
16
задан Benjamin Pollack 23 June 2010 в 13:44
поделиться

1 ответ

Из Документация Python по сигналам :

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

Я тестировал различные классы threading и thread , и ни один из них не работает так, как вы этого хотите - вероятно, это связано с тем, как Python обрабатывает сигналы.

В сигнале , однако, есть функция pause () , которая отключается до тех пор, пока процесс не получит сигнал. Ваш измененный пример будет выглядеть так:

import signal

RUN = True

def handle(a, b):
    global RUN
    print "handled"
    RUN = False

signal.signal(signal.SIGTERM, handle)
while RUN:
    signal.pause()
print "Stopping"

Я проверил его в Linux, он работает. Я не думаю, что он больше классифицируется как опрос и сон, если ваше приложение не использует много других сигналов.

15
ответ дан 30 November 2019 в 22:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: