← Back to blog

Сигналы в Linux

⚙️ Теория

Сигналы в Linux

📖 man 7 signal (man7.org)


🧩 Определение

Сигнал — это асинхронное программное прерывание, используемое ядром Linux для взаимодействия между процессами или между ядром и процессом.
Он служит для уведомления о событии, требующем немедленной реакции, аналогично аппаратным прерываниям на уровне процессора.


⚙️ Классификация сигналов

  • Системные - Управление жизненным циклом процессов
  • Ошибочные - Сообщают об ошибках выполнения
  • Пользовательские - Для пользовательских уведомлений
  • Реального времени (RT) - Очередные и упорядоченные сигналы

🧠 Механизм обработки

Каждый процесс имеет таблицу обработчиков сигналов, связанную со структурой task_struct.
При поступлении сигнала ядро помечает его как pending; для стандартных сигналов одинаковые сигналы обычно не накапливаются в очередь, а для сигналов реального времени (SIGRTMIN..SIGRTMAX) используются очереди с сохранением порядка.

Этапы:

  1. Генерация — сигнал создаётся (kill(), raise(), alarm(), системное событие).
  2. Доставка — ядро ставит сигнал в очередь процесса.
  3. Обработка — выполняется действие по умолчанию или установленный обработчик (signal() / sigaction()).

📡 Примеры сигналов

Номера сигналов могут отличаться между архитектурами; ориентируйтесь на имена (SIGTERM, SIGKILL и т.д.).

СигналКонстантаОписаниеТипичная ситуация
1SIGHUPПотеря управляющего терминалаЗавершение сессии
2SIGINTПрерывание с клавиатурыCtrl+C
9SIGKILLБезусловное завершениеЗавершение зависшего процесса
11SIGSEGVОшибка сегментацииНедопустимый доступ к памяти
15SIGTERMКорректное завершениеСтандартный запрос на остановку
17SIGCHLDПотомок завершилсяОповещение родителя
SIGRTMIN..SIGRTMAXSIGRTMIN–SIGRTMAXРеальное времяПользовательские уведомления

Примеры:

kill(1234, SIGTERM);     // Отправить сигнал процессу
raise(SIGUSR1);          // Послать сигнал самому себе
signal(SIGINT, handler); // Установить обработчик

💻 Примеры системных вызовов

КатегорияСистемный вызовНазначениеПользовательский аналог
Файлыopen(), read(), write(), close()Работа с файловыми дескрипторамиfopen(), fread()
Процессыfork(), execve(), waitpid()Управление процессамиsystem()
Памятьmmap(), brk(), munmap()Управление виртуальной памятьюmalloc()
Времяnanosleep(), clock_gettime()Таймеры и задержкиsleep()
IPCpipe(), msgsnd(), semop()Межпроцессное взаимодействиеPOSIX IPC API
Сетьsocket(), connect(), send(), recv()Сетевые операцииBSD sockets API

Пример:

#include <unistd.h>
#include <sys/wait.h>

pid_t pid = fork();

if (pid == 0) {
    execl("/bin/ls", "ls", "-l", NULL);
} else {
    waitpid(pid, NULL, 0);
}

⚖️ Сравнение: Сигналы vs. Системные вызовы

КритерийСигналСистемный вызов
ПриродаАсинхронное прерываниеСинхронный вызов ядра
ИнициаторЯдро, процесс или сам процессСам процесс
НаправлениеЯдро/процесс → процессПроцесс → ядро
КонтрольНеконтролируемый (асинхронный)Контролируемый (синхронный)
НазначениеУведомление о событииЗапрос системной операции
Передача управленияВ произвольный момент (через обработчик)По вызову процесса
ПримерSIGSEGV, SIGKILL, SIGUSR1read(), fork(), execve()

📚 Академическое резюме

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


🧪 Практика

  • Используйте команды и примеры из разделов выше как рабочий чеклист.
  • Перед применением в production валидируйте изменения на test/stage и сверяйте с официальной документацией.

🧾 Вывод

Сигнал — это асинхронное вмешательство ядра или другого процесса в выполнение процесса.
Системный вызов — это синхронная инициатива процесса на обращение к ядру для выполнения операции.


📚 Ссылки

  • См. ссылки в секции Проверка источников ниже.

Проверка источников

Сигналы в Linux | Aleksandr Suprun