Сигналы, очереди сообщений и семафоры в Linux: основы IPC для DevOps
Сигналы, очереди сообщений и семафоры в Linux — это три столпа межпроцессного взаимодействия (IPC), унаследованные от UNIX и адаптированные под современные DevOps-задачи. Они управляют процессами, передают данные и синхронизируют доступ к ресурсам, оставаясь незаменимыми для контейнеров, оркестрации и распределенных систем. В этой статье мы разберем их историю, теорию, реализацию в ядре Linux и практические примеры, уделяя особое внимание семафорам System V и POSIX.
История сигналов: эволюция от UNIX к Linux
Сигналы появились в UNIX в 1970-х, созданные Деннисом Ритчи и Кеном Томпсоном для уведомления процессов о событиях (SIGINT, SIGCHLD). UNIX System V (1983) интегрировал их в IPC, а POSIX (1980-е) добавил сигналы реального времени (SIGRTMIN–SIGRTMAX). Линус Торвальдс адаптировал их для Linux в 1991 году, и сегодня доступно более 60 сигналов.
История очередей сообщений: System V и POSIX
Очереди сообщений возникли в UNIX System V (1983) с ключами (key_t) и структурой struct msg_queue. POSIX-очереди (POSIX.1b, 1993) интегрированы в /dev/mqueue с приоритетами и уведомлениями, ориентированы на реальное время.
История семафоров: от Дейкстры до Linux
Семафоры изобрел Эдсгер Дейкстра в 1965 году как абстрактный счетчик с операциями P (уменьшение) и V (увеличение) для синхронизации. В UNIX System V (1983) они стали частью IPC для управления доступом между процессами. POSIX (1990-е) ввел именованные и неименованные семафоры в рамках POSIX.1b, улучшив переносимость и поддержку потоков. В Linux оба стандарта сосуществуют: System V для legacy-систем, POSIX для современных приложений.
Теория: сигналы, очереди и семафоры в ядре
Сигналы
- Жизненный цикл: Генерация (
kill,sigqueue) → очередьsigpending→ доставка (get_signal) → (SIG_DFL,SIG_IGN, обработчик). - Реализация:
kernel/signal.c. - Структуры:
struct signal_structвtask_structсsigpending,blocked,sigqueue.
Очереди сообщений
System V:
- Хранение: Цепочка
struct msg_msgвstruct msg_queue. - Управление:
msgsndиmsgrcvс выбором поmtype. - Реализация:
ipc/msg.c.
POSIX:
- Создание:
mq_open("/name", flags)сstruct mq_attr(mq_maxmsg,mq_msgsize). - Хранение: Кольцевой буфер в
/dev/mqueue, сообщения с приоритетами 0–31. - Управление:
mq_send(mq, msg, len, prio): добавляет сообщение по приоритету.mq_receive(mq, buf, size, &prio): извлекает с максимальным приоритетом.mq_notify(mq, &sigev): уведомление через сигналы.
- Реализация:
ipc/mqueue.c.
Семафоры
System V:
- Концепция: массив семафоров (
sem_array), управление черезsemget,semctl,semop. - Хранение:
struct sem_arrayсstruct sem(semval,sempid,semncnt,semzcnt). - Реализация:
ipc/sem.c.
POSIX:
- Концепция: один семафор (
sem_t) с простым API. - Типы:
- Именованные:
sem_open("/name", O_CREAT, mode, value)в/dev/shm. - Неименованные:
sem_init(&sem, pshared, value)в памяти процесса.
- Именованные:
- Управление:
sem_wait(sem): уменьшает, блокирует если 0.sem_post(sem): увеличивает, разблокирует.sem_timedwait(sem, &timeout): ожидание с таймаутом.
- Реализация:
kernel/futex.c,glibc.
Практика для DevOps: примеры
Сигналы
#include#include void handler(int sig) { printf("Сигнал %d\n", sig); } int main() { signal(SIGUSR1, handler); printf("PID: %d\n", getpid()); while (1) sleep(1); }
Очереди сообщений (POSIX)
Отправитель:
#includeint main() { struct mq_attr attr = { .mq_maxmsg = 10, .mq_msgsize = 128 }; mqd_t mq = mq_open("/myqueue", O_CREAT | O_WRONLY, 0644, &attr); mq_send(mq, "High priority", 14, 10); mq_close(mq); return 0; }
Получатель:
#include#include int main() { mqd_t mq = mq_open("/myqueue", O_RDONLY); char buf[128]; unsigned int prio; mq_receive(mq, buf, 128, &prio); printf("Сообщение: %s, приоритет: %u\n", buf, prio); mq_close(mq); mq_unlink("/myqueue"); return 0; }
Итог
Сигналы, очереди и семафоры — это основа IPC в Linux, соединяющая историю UNIX с задачами 2025 года. Сигналы управляют процессами, очереди передают данные, а семафоры синхронизируют доступ: System V с массивами и SEM_UNDO, POSIX с простотой и futex. Изучайте kernel/signal.c, ipc/mqueue.c и ipc/sem.c.

