Под мягкой или безопасной остановкой скрипта понимается такой процесс прерывания, при котором программа «узнает» что её останавливают и запускает часть кода необходимую для корректного завершения программы. Часто такую остановку называют Graceful Exit или Graceful Kill.
Такое поведение может быть полезно например в случае, когда идёт какой-нибудь расчет и требуется приостановить выполнение с возможностью в дальнейшем запустить продолжение из текущей точки останова. Тогда после поступления сигнала на мягкую остановку данные из оперативной памяти не теряются, а записываются на жесткий диск.
Однако более частое применение — это мягкая остановка цикла, когда необходимо перед выходом из программы довести вычисления до логического конца, т.е. полностью закончить текущую итерацию.
Пример Graceful остановки скрипта в цикле:
import signal import time class GracefulKiller: kill_now = False def __init__(self): signal.signal(signal.SIGINT, self.exit_gracefully) signal.signal(signal.SIGTERM, self.exit_gracefully) def exit_gracefully(self,signum, frame): self.kill_now = True # инициализируем "улавливателя" сигналов killer = GracefulKiller() # начинаем вычисления, здесь также может быть альтернативный цикл while True: time.sleep(1) print("doing something in a loop ...") if killer.kill_now: break print "Безопасная остановка успешно заверешена!"
Здесь мы используем два типа сигнала, SIGTERM и SIGINT позволяющие охватить пожалуй все случаи мягкого прерывания.
SIGTERM это основной сигнал, который подает операционная система linux для остановки программы. В отличии от SIGKILL сигнал может быть заблокирован, обработан или же проигнорирован. По умолчанию утилита kill отправляет именно сигнал SIGTERM. Для знакомых с программой htop, попробуйте нажать F9 (kill) и по умолчанию будет выбран именно сигнал -15 SIGTERM, так что это пожалуй самый распространенный способ сказать программе «по доброму» — останавливайся.
Сигнал SIGINT отслеживает остановку процесса пользователем из командной строки, обычно он возникает по Ctrl+с.
Вообще разных сигналов гораздо больше чем SIGTERM и SIGINT, подразделются они на 3 основных класса. Пользовательские (отправляемые пользователем), системные (от ядра системы) и как бы их назвать «программные» (отправляемые другими программами). Возможно для вашей задачи надо будет отлавливать ещё что-то, но 99.9% должно хватить скрипта сверху