В чем различия сигналов SIGKILL и SIGTERM?

Ответ

SIGTERM (Signal 15, kill по умолчанию) и SIGKILL (Signal 9, kill -9) — это сигналы операционной системы, используемые для управления процессами, но они имеют принципиальные различия в поведении:

  • SIGTERM (Terminate Signal)

    • Тип: "Вежливый" запрос на завершение.
    • Перехватываемость: Процесс может перехватить этот сигнал и обработать его.
    • Поведение: Дает процессу возможность выполнить операции по очистке: сохранить данные, закрыть файлы, освободить ресурсы, корректно завершить дочерние процессы.
    • Цель: Обеспечить грамотное завершение работы без потери данных или повреждения состояния.
  • SIGKILL (Kill Signal)

    • Тип: "Жесткое" принудительное завершение.
    • Перехватываемость: Процесс не может перехватить или игнорировать этот сигнал.
    • Поведение: Операционная система немедленно и принудительно завершает процесс. Процесс не получает возможности выполнить какие-либо действия по очистке.
    • Цель: Гарантированное завершение процесса, когда он не реагирует на другие сигналы.

Ключевое отличие: Возможность процесса обработать сигнал и выполнить очистку.

Пример обработки SIGTERM в Python:

import signal
import sys
import time

def handle_sigterm(signum, frame):
    print(f"[{time.time():.2f}] Получен SIGTERM ({signum}). Начинаю корректное завершение...")
    # Здесь можно выполнить очистку: закрыть соединения, сохранить состояние и т.д.
    time.sleep(1) # Имитация работы по очистке
    print(f"[{time.time():.2f}] Очистка завершена. Выход.")
    sys.exit(0)

# Регистрируем обработчик для SIGTERM
signal.signal(signal.SIGTERM, handle_sigterm)

print(f"[{time.time():.2f}] Процесс запущен. Ожидаю сигналы...")
try:
    while True:
        time.sleep(5) # Имитация полезной работы
except KeyboardInterrupt:
    print(f"[{time.time():.2f}] Получен KeyboardInterrupt (Ctrl+C), выход.")
    sys.exit(0)

Если отправить kill <PID> (что по умолчанию отправляет SIGTERM) этому скрипту, он выведет сообщение о получении сигнала и корректно завершится. Если отправить kill -9 <PID> (SIGKILL), процесс будет немедленно остановлен без вывода сообщений обработчика.

Рекомендация: Всегда следует сначала пытаться завершить процесс с помощью SIGTERM. Если процесс не реагирует в течение разумного времени (например, 5-10 секунд), тогда можно использовать SIGKILL как крайнюю меру. Это минимизирует риск потери данных и повреждения состояния системы.