В чем разница между сигналами SIGTERM (kill -15) и SIGKILL (kill -9) в Linux?

Ответ

Это два разных сигнала, используемых для завершения процессов в Unix-подобных системах, но они работают принципиально по-разному.

kill -15 (SIGTERM)

  • "Вежливый" запрос на завершение. Это сигнал по умолчанию для утилиты kill. Он сообщает процессу, что его просят завершиться.
  • Можно перехватить. Приложение может (и должно) перехватить этот сигнал, чтобы выполнить очистку: сохранить данные, закрыть файлы и сетевые соединения, завершить дочерние процессы.
  • Может быть проигнорирован. Процесс может проигнорировать SIGTERM, если он занят или некорректно написан.

kill -9 (SIGKILL)

  • Принудительное "убийство". Этот сигнал нельзя перехватить, заблокировать или проигнорировать.
  • Немедленное завершение. Ядро системы немедленно останавливает выполнение процесса, не давая ему шанса на очистку.
  • Опасность. Использование SIGKILL может привести к повреждению данных, оставленным "зомби"-процессам и утечкам ресурсов (например, временные файлы не будут удалены).

Пример перехвата SIGTERM в Go:

package main

import (
    "fmt"
    "os"
    "os/signal"
    "syscall"
    "time"
)

func main() {
    // Создаем канал для получения сигналов ОС
    sigChan := make(chan os.Signal, 1)
    // Уведомляем наш канал о поступлении SIGINT или SIGTERM
    signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)

    fmt.Println("Процесс запущен (PID: ", os.Getpid(), "). Ожидание сигнала...")

    // Блокируемся, пока не получим сигнал
    sig := <-sigChan
    fmt.Printf("nПолучен сигнал: %s. Начинаю корректное завершение...n", sig)

    // Здесь происходит логика очистки
    fmt.Println("Закрываю соединения, сохраняю состояние...")
    time.Sleep(2 * time.Second)

    fmt.Println("Работа завершена.")
}

Итог: Всегда следует сначала отправлять SIGTERM и давать процессу время на завершение. SIGKILL — это крайняя мера, которую стоит применять, только если процесс не отвечает на SIGTERM.

Ответ 18+ 🔞

Ага, слушай, вот тебе на пальцах, как эти два сигнала работают, а то народ путает, как хуй с пальцем.

kill -15 (SIGTERM) — это вежливый стук в дверь

Представь, ты сидишь, кодишь, а тебе говорят: «Э, дружок, закругляйся, пожалуйста». Это SIGTERM. Он такой культурный, блядь.

  • Процессу дают шанс. Он может этот сигнал перехватить и сделать всё красиво: сохранить данные, закрыть все файлы, попрощаться с дочерними процессами — в общем, прибраться на своей кухне.
  • Можно послать на хуй. Если процесс кривой или просто задумался, он может этот сигнал проигнорировать. И продолжит висеть, как сонная муха.

kill -9 (SIGKILL) — это вышибание двери с плеча

А это уже не просьба. Это когда врываются с криком «Руки вверх, ёбта!» и стреляют без разговоров. Это SIGKILL.

  • Никаких переговоров. Этот сигнал нельзя перехватить, заблокировать или проигнорировать. Ядро системы просто берёт и вырубает процесс нахуй, моментально.
  • Опасная штука. Вот поэтому он последний аргумент. Процесс не успеет нихуя сделать: данные могут повредиться, файлы останутся открытыми, дети-процессы осиротеют — пиздец, короче, бардак.

Смотри, как можно ловить этот вежливый SIGTERM на Go, чтобы красиво завершиться:

package main

import (
    "fmt"
    "os"
    "os/signal"
    "syscall"
    "time"
)

func main() {
    // Делаем канал, куда нам будут сигналы с операционки падать
    sigChan := make(chan os.Signal, 1)
    // Говорим системе: «Слушай, чувак, как только будет SIGINT (Ctrl+C) или SIGTERM (kill -15) — шли сюда!»
    signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)

    fmt.Println("Процесс запущен (PID: ", os.Getpid(), "). Сижу, жду сигнала...")

    // Тут мы зависаем, ждём-с
    sig := <-sigChan
    fmt.Printf("nОпа, пришёл сигнал: %s. Щас всё по-красивому сделаю...n", sig)

    // А вот тут как раз та самая уборка перед смертью
    fmt.Println("Закрываю соединения, сохраняю состояние... делаю вид, что я ответственный...")
    time.Sleep(2 * time.Second) // Симулирую работу

    fmt.Println("Всё, прибрался. Пока!")
}

Итог, блядь, простой: сначала всегда SIGTERM (kill -15). Дай процессу пару секунд, пусть уйдёт с достоинством. А SIGKILL (kill -9) — это уже когда терпения ебать ноль, и этот мудак-процесс вообще не реагирует. Тогда уже — в топку его, без церемоний.