Средства межпроцессного взаимодействия
Средства локального межпроцессного взаимодействия реализуют высокопроизводительную, детерминированную передачу данных между процессами в пределах одной системы.
К числу наиболее простых и в то же время самых употребительных средств межпроцессного взаимодействия принадлежат каналы, представляемые файлами соответствующего типа. Стандарт POSIX-2001 различает именованные и безымянные каналы.
Взаимодействие между процессами через канал может быть установлено следующим образом: один из процессов с помощью функций popen() или pipe() создает канал и передает другому соответствующий открытый файловый дескриптор. После этого процессы обмениваются данными через канал посредством функций read() и write().
По сравнению с pipe() функция popen() является более высокоуровневой. Она делает сразу несколько вещей: порождает процесс, обеспечивает выполнение заданной команды в его рамках, организует канал между вызывающим и порожденным процессами и формирует необходимые потоки для этого канала.
Канал остается открытым до тех пор, пока не будет вызвана функция pclose().
Согласно стандарту POSIX-2001, под сигналом понимается механизм, с помощью которого процесс или поток управления уведомляют о некотором событии, произошедшем в системе, или подвергаются воздействию этого события.
В каждом процессе определены действия, предпринимаемые в ответ на все предусмотренные системой сигналы.
У каждого потока управления есть маска сигналов, определяющая набор блокируемых сигналов.
С сигналом могут быть ассоциированы действия одного из трех типов.
SIG_DFL
Подразумеваемые действия, зависящие от сигнала. Они описаны в заголовочном файле <signal.h>.
SIG_IGN
Игнорировать сигнал. Доставка сигнала не оказывает воздействия на процесс .
Указатель на функцию
Обработать сигнал, выполнив при его доставке заданную функцию. После завершения функции обработки процесс возобновляет выполнение с точки прерывания.
К средствам генерации сигналов относятся служебная программа и одноименная функция.
Процесс (поток управления) может послать сигнал самому себе с помощью функции raise().
Функция abort() вызывает аварийное завершение процесса.
Опросить и изменить способ обработки сигналов позволяет функция sigaction().
Опросить и изменить способ обработки сигналов можно и на уровне командного интерпретатора, посредством специальной встроенной команды trap.
К техническим аспектам можно отнести работу с наборами сигналов. Ее выполняют инициализирующие набор функции sigemptyset() и sigfillset(), добавляющая сигнал signo к набору set функция sigaddset(),удаляющая сигнал функция sigdelset() и проверяющая вхождение в набор функция sigismember().
Функция sigprocmask() предназначена для опроса и/или изменения маски сигналов процесса, определяющей набор блокируемых сигналов.
Функция sigpending() позволяет выяснить набор блокированных сигналов, ожидающих доставки вызывающему процессу (потоку управления). Дождаться появления подобного сигнала можно с помощью функции sigwait().
Функция pause() поможет дождаться доставки обрабатываемого или терминирующего процесс сигнала.
Функция sigsuspend() заменяет текущую маску сигналов вызывающего процесса, а затем переходит в состояние ожидания. Обычно парой функций sigprocmask() и sigsuspend() обрамляют критические интервалы.
Очереди сообщений, семафоры и разделяемые сегменты памяти отнесены к необязательной части стандарта POSIX-2001, именуемой "X/Open-расширение системного интерфейса"(XSI).
Каждую очередь сообщений, набор семафоров и разделяемый сегмент однозначно идентифицирует положительное целое число, которое возвращается в качестве результатов функций msgget(), semget() и shmget().
При получении идентификаторов средств межпроцессного взаимодействия используется еще одна сущность - ключ, для его генерации предназначена функция ftok().
Опросить статус присутствующих в данный момент в системе (активных) средств межпроцессного взаимодействия позволяет служебная программа ipcs.
Для удаления из системы активных средств межпроцессного взаимодействия предназначена служебная программа ipcrm.
Механизм очередей сообщений позволяет процессам взаимодействовать, обмениваясь данными, которые передаются между процессами дискретными порциями, называемыми сообщениями.
процессы выполняют над сообщениями две основные операции - прием и отправку.
Для работы с очередями сообщений в стандарте POSIX-2001 предусмотрены следующие функции: msgget() - получение идентификатора очереди сообщений, msgctl() - управление очередью сообщений, msgsnd() - отправка сообщения, msgrcv() - прием сообщения.
Согласно определению стандарта POSIX-2001, семафор - это минимальный примитив синхронизации, служащий основой для более сложных механизмов синхронизации, определенных в прикладной программе.
У семафора есть значение, которое представляется целым числом в диапазоне от 0 до 32767.
Семафоры создаются функцией semget() и обрабатываются функцией semop() определенными наборами (массивами), причем операции над наборами с точки зрения приложений являются атомарными. В рамках групповых операций для любого семафора из набора можно сделать следующее: увеличить значение, уменьшить значение, дождаться обнуления.
Процессы, обладающие соответствующими правами, могут выполнять также различные управляющие действия над семафорами. Для этого служит функция semctl().
В стандарте POSIX-2001 разделяемый объект памяти определяется как объект, представляющий собой память, которая может быть параллельно отображена в адресное пространство более чем одного процесса.
Работа с разделяемой памятью начинается с того, что один из взаимодействующих процессов посредством функции shmget() создает разделяемый сегмент, специфицируя первоначальные права доступа к нему и его размер в байтах.
Для получения доступа к разделяемому сегменту его нужно присоединить посредством функции shmat(), т.е. Разместить сегмент в виртуальном пространстве процесса. После присоединения, в соответствии с правами доступа, процессы могут читать данные из сегмента и записывать их (быть может, синхронизируя свои действия с помощью семафоров). Когда разделяемый сегмент становится ненужным, его следует отсоединить с помощью функции shmdt().
Предусмотрена возможность выполнения управляющих действий над разделяемыми сегментами (функция shmctl()).