Gymterview
middle

Что такое сигналы в Unix/Linux?

Сигналы — это асинхронные уведомления, отправляемые процессам ядром или другими процессами для управления их поведением. Каждый сигнал имеет номер и символическое имя.

Аналогия

Сигналы — как записки, которые менеджер (ядро ОС) может передать работнику (процессу). Одни записки — вежливые просьбы («пожалуйста, завершай работу» — SIGTERM), на которые работник может отреагировать по-своему. Другие — приказы, которые нельзя проигнорировать («ты уволен, охрана выведет» — SIGKILL).

Основные сигналы

Сигнал Номер Описание Можно перехватить?
SIGHUP 1 Потеря терминала. Демоны перечитывают конфигурацию Да
SIGINT 2 Прерывание (Ctrl+C) Да
SIGQUIT 3 Quit (Ctrl+\), core dump Да
SIGKILL 9 Принудительное завершение Нет
SIGUSR1 10 Пользовательский сигнал 1. В JVM: thread dump Да
SIGUSR2 12 Пользовательский сигнал 2 Да
SIGTERM 15 Мягкое завершение (по умолчанию для kill) Да
SIGCONT 18 Продолжить приостановленный процесс Да
SIGSTOP 19 Приостановка процесса Нет
SIGTSTP 20 Terminal Stop (Ctrl+Z) Да

Отправка сигналов

Пример
kill -SIGTERM 1234               # По имени
kill -15 1234                    # По номеру
kill 1234                        # SIGTERM по умолчанию
kill -9 1234                     # SIGKILL — крайняя мера

Сигналы и Java-приложения

SIGTERM (kill, kill -15) — правильный способ остановки Java-приложения. JVM получает сигнал, выполняет shutdown hooks (зарегистрированные через Runtime.addShutdownHook()), Spring Boot корректно завершает контексты, закрывает пулы соединений.

SIGKILL (kill -9) — немедленное уничтожение процесса ядром ОС. JVM не имеет возможности выполнить shutdown hooks, ресурсы не освобождаются, транзакции не откатываются. Используйте только если процесс завис и не реагирует на SIGTERM.

Пример
# Получить thread dump Java-процесса (полезно при диагностике зависаний)
kill -3 <java_pid>                # SIGQUIT — JVM выведет thread dump в stdout
jstack <java_pid>                 # Альтернатива через утилиту JDK

Перехват сигналов в bash-скрипте (trap)

Пример
#!/bin/bash
# Очистка при получении SIGTERM или SIGINT
cleanup() {
    echo "Cleaning up..."
    rm -f /tmp/myapp.lock
    exit 0
}
trap cleanup SIGTERM SIGINT

echo "Working... PID=$$"
while true; do
    sleep 1
done

На собеседовании: интервьюер хочет проверить, знаете ли вы разницу между SIGTERM и SIGKILL, и почему нельзя начинать с kill -9. Частая ошибка — не знать, что SIGKILL нельзя перехватить, и что JVM при нём не выполняет shutdown hooks, что может привести к потере данных.