Оглавление

Сигналы, очереди сообщений и семафоры в 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.
Сигналы, очереди и семафоры в Linux: от истоков до ядра и DevOps

Практика для 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.