Что такое сигналы в 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, что может привести к потере данных.