Я натыкался на эту проблему, в то время как я пытался ответить на вопрос на Stackoverflow.
На завершении работы отправляет Ubuntu 12.04 SIGTERM
ко всем процессам и ожидает самое большее 10 секунд прежде, чем уничтожить их с SIGKILL
(если они не завершили прежде). Мой ответ на ПОЭТОМУ даже содержит сценарий Python, который проверяет то поведение. Сценарий запускается в терминале, отправленном в фон и, чем отрицаемый терминалом. При получении SIGTERM
, сценарий просто продолжает идти и непрерывно печатает в файл, сколько времени он бежал за получением SIGTERM
.
Ubuntu 16.04 однако, сценарий сразу уничтожается на завершении работы (нет SIGTERM
зарегистрирован).
Я погуглил некоторое время, но я ничто не мог найти полезным. Никто никогда не сталкивался с тем изменением повреждения для текущего выпуска LTS?
Вот сценарий signaltest.py
import signal
import time
stopped = False
out = open('log.txt', 'w')
def stop(sig, frame):
global stopped
stopped = True
out.write('caught SIGTERM\n')
out.flush()
signal.signal(signal.SIGTERM, stop)
while not stopped:
out.write('running\n')
out.flush()
time.sleep(1)
stop_time = time.time()
while True:
out.write('%.4fs after stop\n' % (time.time() - stop_time))
out.flush()
time.sleep(0.1)
Сценарий использует файл log.txt
в текущем каталоге для всего вывода. Это имеет цикл, который печатает 'выполнение' каждую секунду. Получение SIGTERM
повреждается ответ цикла запускает другой цикл, который печатает секунды, истекшие начиная с получения SIGTERM
.
Скрипт запущен от терминала отдельное использование disown
:
python signaltest.py &
disown
Только быть ясным: Это не дубликат Ubuntu, не отправляет SIGTERM на завершении работы. Вопрос о настольных приложениях, и ответы не соответствуют также.
systemd (настроенный против выскочки в более ранних вирионах Ubuntu) дополнительно отправляет SIGHUP на завершении работы (и ожидает 90-е вместо 10-х прежде, чем отправить SIGKILL
). Я предлагаю проигнорировать SIGHUP
или обработать SIGTERM
и SIGHUP
тот же (идемпотентный) путь.
измененный сценарий тестирования мог быть изменен как это:
import signal
import time
stopped = False
out = open('log.txt', 'w')
def stop(sig, frame):
global stopped
stopped = True
out.write('caught SIGTERM\n')
out.flush()
def ignore(sig, frsma):
out.write('ignoring signal %d\n' % sig)
out.flush()
signal.signal(signal.SIGTERM, stop)
signal.signal(signal.SIGHUP, ignore)
while not stopped:
out.write('running\n')
out.flush()
time.sleep(1)
stop_time = time.time()
while True:
out.write('%.4fs after stop\n' % (time.time() - stop_time))
out.flush()
time.sleep(0.1)