Сигналы, очереди сообщений и семафоры в 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 <signal.h>
#include <stdio.h>
void handler(int sig) { printf("Сигнал %d\n", sig); }
int main() {
signal(SIGUSR1, handler);
printf("PID: %d\n", getpid());
while (1) sleep(1);
}
Очереди сообщений (POSIX)
Отправитель:
#include <mqueue.h>
int 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 <mqueue.h>
#include <stdio.h>
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.
