Это должно быть очень просто, и я очень удивлен, что мне не удалось найти ответы на эти вопросы уже в stackoverflow.
У меня есть программа вроде демона, которая должна отвечать на сигналы SIGTERM и SIGINT, чтобы хорошо работать с выскочкой. Я читал, что лучший способ сделать это - запустить основной цикл программы в отдельном потоке из основного потока и позволить основному потоку обрабатывать сигналы. Затем, когда принимается сигнал, обработчик сигнала должен сообщать основному циклу о выходе, установив флаг часового, который обычно проверяется в основном цикле.
Я пытался это сделать, но он не работает так, как я ожидал. См. Код ниже:
from threading import Thread
import signal
import time
import sys
stop_requested = False
def sig_handler(signum, frame):
sys.stdout.write("handling signal: %s\n" % signum)
sys.stdout.flush()
global stop_requested
stop_requested = True
def run():
sys.stdout.write("run started\n")
sys.stdout.flush()
while not stop_requested:
time.sleep(2)
sys.stdout.write("run exited\n")
sys.stdout.flush()
signal.signal(signal.SIGTERM, sig_handler)
signal.signal(signal.SIGINT, sig_handler)
t = Thread(target=run)
t.start()
t.join()
sys.stdout.write("join completed\n")
sys.stdout.flush()
Я проверил это двумя способами:
1)
$ python main.py > output.txt&
[2] 3204
$ kill -15 3204
2)
$ python main.py
ctrl+c
В обоих случаях я ожидаю, что это будет записано в вывод:
run started
handling signal: 15
run exited
join completed
В первом случае программа выходит, но все, что я вижу, это:
run started
Во втором случае сигнал SIGTERM, по-видимому, игнорируется при нажатии ctrl + c, и программа не выходит.
Что мне здесь не хватает?