Сигналы в Linux

Oct, 20, 2025

Сигналы в Linux

📖 man 7 signal (man7.org)


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

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


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

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

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

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

Этапы:

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

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

СигналКонстантаОписаниеТипичная ситуация
1SIGHUPПотеря управляющего терминалаЗавершение сессии
2SIGINTПрерывание с клавиатурыCtrl+C
9SIGKILLБезусловное завершениеЗавершение зависшего процесса
11SIGSEGVОшибка сегментацииНедопустимый доступ к памяти
15SIGTERMКорректное завершениеСтандартный запрос на остановку
17SIGCHLDПотомок завершилсяОповещение родителя
30–64SIGRTMIN–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()

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

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


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

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