Ряд реализаций UNIX, включая дистрибутивы Linux, в которых библиотека glibc поддерживает NPTL-потоки, позволяют разделять между процессами мьютексы и условные переменные. Эта возможность предусмотрена стандартом SUSv3, но не является обязательной. Она поддерживается не во всех UNIX-системах и обычно не используется для синхронизации процессов.
При выборе средства для межпроцессной синхронизации обычно учитываются функциональные требования. Для координации доступа к файлу лучшим выбором, как правило, является блокировка записей. Для координации доступа к другим видам общих ресурсов часто выбирают семафоры.
Средства взаимодействия тоже могут использоваться для синхронизации. Например, в разделе 44.3 будет показано, как синхронизировать действия родительского и дочернего процессов с помощью канала. В целом синхронизация может быть выполнена за счет любого механизма передачи данных; в таких случаях это выглядит как обмен сообщениями, проходящими через выбранный механизм.
Когда речь заходит об IPC, мы сразу же сталкиваемся с разнообразием вариантов, которое поначалу может вызвать недоумение. В следующих главах, описывающих каждый из IPC-механизмов, есть разделы, в которых сравниваются несколько похожих средств. Ниже мы рассмотрим несколько общих моментов, способных повлиять на выбор того или иного механизма.
Чтобы получить доступ к IPC-объекту, у процесса должна быть возможность его идентифицировать; после «открытия» объекта процесс должен использовать некий дескриптор, который на него ссылается. Эти свойства в контексте разных видов IPC-механизмов перечислены в табл. 43.1.
Таблица 43.1. Идентификаторы и дескрипторы в различных видах IPC-механизмов
Механизм — Имя для идентификации объекта — Дескриптор, ссылающийся на объект в программе
Канал — Без имени — Дескриптор файла
Очередь FIFO — Pathname — Дескриптор файла
Сокет домена UNIX — Pathname — Дескриптор файла
Сокет интернет-домена — IP-адрес + номер порта — Дескриптор файла
Очередь сообщений в System V–IPC-ключ в System V–IPC-идентификатор в System V
Семафор в System V–IPC-ключ в System V–IPC-идентификатор в System V
Разделяемая память в System V–IPC-ключ в System V–IPC-идентификатор в System V
Очередь POSIX-сообщений — IPC-путь в POSIX — mqd_t (дескриптор очереди сообщений)
Именованный POSIX-семафор — IPC-путь в POSIX — sem_t * (указатель на семафор)
Безымянный POSIX-семафор — Без имени — sem_t * (указатель на семафор)
Разделяемая память в POSIX–IPC-путь в POSIX — Дескриптор файла
Анонимное отображение — Без имени — Отсутствует
Файл, отображенный в память — Pathname — Дескриптор файла
Блокировка flock() — Pathname — Дескриптор файла
Блокировка fcntl() — Pathname — Дескриптор файла
Существуют функциональные различия, которые могут повлиять на выбор того или иного IPC-механизма. Для начала кратко перечислим различия между средствами передачи данных и разделяемой памятью.
• Средства передачи данных используют операции чтения и записи, а переданная информация потребляется только одним процессом-адресатом. Управление потоком данных между отправителем и получателем, а также их синхронизация (чтобы блокировать получателя, который пытается прочитать данные из пустого источника) автоматически осуществляется ядром. Эта модель хорошо согласуется с архитектурой многих приложений.