← Назад к вопросам
Зачем нужны сигналы в Linux?
2.0 Middle🔥 161 комментариев
#Linux и администрирование
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Сигналы в Linux: назначение и роль
Сигналы (signals) — это механизм асинхронной межпроцессной коммуникации в Linux, который позволяет ОС и процессам отправлять друг другу уведомления о возникших событиях, не дожидаясь синхронного запроса.
Основное назначение сигналов
Сигналы решают проблему асинхронности:
- Процесс может быть прерван в любой момент
- ОС уведомляет процесс о событиях (сигнал от клавиатуры, таймер истёк, дочерний процесс завершился)
- Процесс может определить свой обработчик сигнала (signal handler)
Основные применения сигналов
1. Управление процессом
# SIGTERM — корректное завершение
kill -TERM <pid>
# SIGKILL — насильственное завершение (нельзя перехватить)
kill -KILL <pid>
# SIGSTOP/SIGCONT — приостановка и возобновление
kill -STOP <pid>
kill -CONT <pid>
2. Обработка ошибок и исключений
# SIGSEGV — ошибка сегментации (доступ в неправильную память)
# SIGABRT — вызов abort()
# SIGFPE — ошибка вычислений (деление на 0)
# SIGILL — некорректная инструкция
3. Работа с вводом-выводом
# SIGINT — Ctrl+C (прерывание)
# SIGQUIT — Ctrl+\ (выход)
# SIGHUP — закрытие терминала
4. Таймеры и события
# SIGALRM — таймер (из alarm())
# SIGCHLD — дочерний процесс завершился
# SIGPIPE — запись в закрытый канал
Как процесс обрабатывает сигналы
На bash:
#!/bin/bash
# Определяем обработчик сигнала
trap 'echo "Получен сигнал SIGTERM, завершаю..."' TERM
trap 'echo "Получен сигнал SIGINT, отменяю операцию"' INT
echo "PID: $$"
echo "Ожидаю сигналы..."
while true; do
sleep 1
done
На Python:
import signal
import time
def sigterm_handler(signum, frame):
print("Получен SIGTERM, завершаю корректно...")
exit(0)
def sigint_handler(signum, frame):
print("\nПолучен SIGINT (Ctrl+C)")
exit(1)
# Регистрируем обработчики
signal.signal(signal.SIGTERM, sigterm_handler)
signal.signal(signal.SIGINT, sigint_handler)
print(f"PID: {os.getpid()}")
while True:
time.sleep(1)
Практические примеры в DevOps
Graceful shutdown в Docker:
FROM python:3.9
WORKDIR /app
COPY app.py .
CMD ["python", "app.py"]
# app.py
import signal
import sys
def graceful_shutdown(signum, frame):
print("Shutdown signal received, cleaning up...")
# Закрываем DB connections, flush logs
sys.exit(0)
signal.signal(signal.SIGTERM, graceful_shutdown)
Перезагрузка конфига (Nginx):
# nginx перечитывает конфиг без перезагрузки
nginx -s reload # отправляет SIGHUP процессу
Мониторинг дочерних процессов:
while true; do
child_process &
pid=$!
# Перехватываем SIGCHLD (дочерний завершился)
trap 'wait $pid; echo "Child exited with code $?"' SIGCHLD
wait $pid
done
Типичные сигналы и их коды
| Сигнал | Код | Значение | Перехватывается |
|---|---|---|---|
| SIGTERM | 15 | Завершение | Да |
| SIGKILL | 9 | Убить процесс | Нет |
| SIGINT | 2 | Ctrl+C | Да |
| SIGSTOP | 19 | Приостановить | Нет |
| SIGCONT | 18 | Продолжить | Да |
| SIGCHLD | 17 | Дочерний завершился | Да |
| SIGHUP | 1 | Закрытие терминала | Да |
| SIGUSR1/2 | 10/12 | Пользовательские | Да |
Почему это важно для DevOps
- Graceful shutdown: Даём приложению время на очистку ресурсов
- Zero-downtime deployment: Перенаправляем запросы, затем корректно завершаем старый процесс
- Управление ресурсами: Приостанавливаем и возобновляем процессы
- Мониторинг: Отслеживаем состояние дочерних процессов
- Конфигурация: Перезагружаем конфиг без перезагрузки (SIGHUP)