

13. Средства межпроцессорного взаимодействия UNIX
Механизмы межпроцессного взаимодействия, затрагиваемые в этой работе, являются более редкими. В общем случае эти средства описываются как средства IPC (inter-process communication - межпроцессное взаимодействие). Этот общий термин подчеркивает общность их применения и структуры, хотя существуют три определенных типа таких средств.
- очереди сообщений (message passing). Они позволяют процессу посылать и принимать сообщения, под которыми понимается произвольная последовательность байтов или символов;
- семафоры (semaphores). По сравнению с очередями сообщений семафоры представляют собой низкоуровневый метод синхронизации процессов, малопригодный для передачи больших объемов данных;
- разделяемая память (shared memory). Это средство межпроцессного взаимодействия позволяет двум и более процессам совместно использовать данные, содержащиеся в определенных сегментах памяти. Естественно, обычно данные процесса являются недоступными для других процессов. Этот механизм обычно является самым быстрым механизмом межпроцессного взаимодействия.
ОС UNIX предлагает множество дополнительных механизмов межпроцессного взаимодействия. Их наличие дает UNIX богатые возможности в области связи между процессами и позволяет разработчику использовать различные подходы при программировании многозадачных систем. Дополнительные средства межпроцессного взаимодействия, которые будут рассмотрены, можно разбить на следующие категории:
- передача сообщений;
- семафоры;
- разделяемая память.
Программный интерфейс всех трех средств IPC однороден, что отражает схожесть их реализации в ядре. Наиболее важным из общих свойств является ключ (key). Ключи - это числа, обозначающие объект межпроцессного взаимодействия в системе UNIX примерно так же, как имя файла обозначает файл. Другими словами, ключ позволяет ресурсу межпроцессного взаимодействия совместно использоваться несколькими процессами. Обозначаемый ключом объект может быть очередью сообщения, набором семафоров или сегментом разделяемой памяти. Ключ имеет тип key_t, состав которого зависит от реализации и определяется в системном заголовочном файле.
Ключи не являются именами файлов и несут меньший смысл. Они должны выбираться осторожно во избежание конфликта между различными программами, в этом помогает применение дополнительной опции - «версии проекта». В ОС UNIX существует простая библиотечная функция ftok, которая образует ключ по указанному файлу.
Программа применяет ключ для создания объекта межпроцессного взаимодействия или получения доступа к существующему объекту. Обе операции вызываются при помощи операции get. Результатом операции get является его целочисленный идентификатор (facility identifier), который может использоваться при вызовах других процедур межпроцессного взаимодействия. Операция get похожа на вызов creat или open, а идентификатор средства межпроцессного взаимодействия ведет себя подобно дескриптору файла.
Есть еще два типа операций, которые применимы к средствам межпроцессного взаимодействия: операции управления, которые используются для опроса и изменения статуса объекта IPC, их функции выполняют вызовы msgctl, semctl и shmctl; операции, выполняющие основные функции IPC.
При создании объекта межпроцессного взаимодействия система также создает структуру статуса средства межпроцессного взаимодействия (IPC facility status structure), содержащую всю управляющую информацию, связанную с объектом. Для сообщений, семафоров и разделяемой памяти существуют разные типы структуры статуса.
uid_t uid; /*Действующий идентификатор пользователя*/
Права доступа определяют, может ли пользователь выполнять «чтение» из объекта (получать информацию о нем) или «запись» в объект (работать с ним). Коды прав доступа образуются точно таким же образом, как и для файлов. Права доступа, заданные элементом umode, применяются в сочетании с действующими идентификаторами пользователя и группы. Значение переменной umask пользователя не действует при создании средства межпроцессного взаимодействия.
Сообщение является просто последовательностью символов или байтов (необязательно заканчивающейся нулевым символом). Сообщения передаются между процессами при помощи очередей сообщений (message queues), которые можно создавать или получать к ним доступ при помощи вызова msgget. После создания очереди процесс может помещать в нее сообщения при помощи вызова msgsnd, если он имеет соответствующие права доступа. Затем другой процесс может считать это сообщение при помощи примитива msgrcv, который извлекает сообщение из очереди.
Первый из вызовов, msgsnd, используется для добавления сообщения в очередь, обозначенную идентификатором mqid.
Для чтения из очереди, заданной идентификатором mqid, используется вызов msgrcv. Чтение разрешено, если процесс имеет права доступа к очереди на чтение. Успешное чтение сообщения приводит к удалению его из очереди.
Процедура msgctl служит трем целям: она позволяет процессу получать информацию о статусе очереди сообщений, изменять некоторые из связанных с очередью ограничений или удалять очередь из системы.
В информатике понятие семафор (semaphore) был впервые введено для решения задач синхронизации процессов. Семафор sem может рассматриваться как целочисленная переменная
Действия проверки и установки в обеих операциях должны составлять одно атомарное действие, чтобы только один процесс мог изменять семафор sem в каждый момент времени.
Семафоры могут использоваться несколькими способами. Наиболее простой из них заключается в обеспечении взаимного исключения (mutual exclusion), когда только один процесс может выполнять определенный участок кода одновременно.
Реализация семафоров в ОС UNIX основана на этой теоретической идее, хотя в действительности, предлагаемые средства являются более общими.
Вызов semget аналогичен вызову msgget. Дополнительный параметр nsems задает требуемое число семафоров в наборе семафоров. Это важный момент - семафорные операции в IPC приспособлены для работы с наборами семафоров, а не с отдельными объектами семафоров.
Значение, возвращаемое в результате успешного вызова semget, является идентификатором набора семафоров (semaphore set identifier), который ведет себя почти так же, как идентификатор очереди сообщений. Индекс семафора в наборе может принимать значения от 0 до (nsems-1).
С каждым семафором в наборе связаны следующие значения:
- semval - значение семафора, положительное целое число. Устанавливается при помощи системных вызовов работы с семафорами, то есть к значениям семафоров нельзя получить прямой доступ из программы, как к другим объектам данных;
- sempid - идентификатор процесса, который последним работал с семафором;
- semncnt - число процессов, ожидающих увеличения значения семафора;
- semzcnt - число процессов, ожидающих обнуления значения семафора.
Разделяемая память
Операции с разделяемой памятью позволяют двум и более процессам совместно использовать область физической памяти (общеизвестно, что обычно области данных любых двух программ совершенно отделены друг от друга). Чаще всего разделяемая память является наиболее производительным механизмом межпроцессного взаимодействия.
Для того чтобы сегмент памяти мог использоваться совместно, он должен быть сначала создан при помощи системного вызова shmget. После создания сегмента разделяемой памяти процесс может подключаться к нему при помощи вызова shmat и затем использовать его для своих частных целей. Когда этот сегмент памяти больше не нужен, процесс может отключиться от него при помощи вызова shmdt.
Сегменты разделяемой памяти создаются при помощи вызова shmget.
- очереди сообщений (message passing). Они позволяют процессу посылать и принимать сообщения, под которыми понимается произвольная последовательность байтов или символов;
- семафоры (semaphores). По сравнению с очередями сообщений семафоры представляют собой низкоуровневый метод синхронизации процессов, малопригодный для передачи больших объемов данных;
- разделяемая память (shared memory). Это средство межпроцессного взаимодействия позволяет двум и более процессам совместно использовать данные, содержащиеся в определенных сегментах памяти. Естественно, обычно данные процесса являются недоступными для других процессов. Этот механизм обычно является самым быстрым механизмом межпроцессного взаимодействия.
Основные понятия
ОС UNIX предлагает множество дополнительных механизмов межпроцессного взаимодействия. Их наличие дает UNIX богатые возможности в области связи между процессами и позволяет разработчику использовать различные подходы при программировании многозадачных систем. Дополнительные средства межпроцессного взаимодействия, которые будут рассмотрены, можно разбить на следующие категории:
- передача сообщений;
- семафоры;
- разделяемая память.
Программный интерфейс всех трех средств IPC однороден, что отражает схожесть их реализации в ядре. Наиболее важным из общих свойств является ключ (key). Ключи - это числа, обозначающие объект межпроцессного взаимодействия в системе UNIX примерно так же, как имя файла обозначает файл. Другими словами, ключ позволяет ресурсу межпроцессного взаимодействия совместно использоваться несколькими процессами. Обозначаемый ключом объект может быть очередью сообщения, набором семафоров или сегментом разделяемой памяти. Ключ имеет тип key_t, состав которого зависит от реализации и определяется в системном заголовочном файле
Ключи не являются именами файлов и несут меньший смысл. Они должны выбираться осторожно во избежание конфликта между различными программами, в этом помогает применение дополнительной опции - «версии проекта». В ОС UNIX существует простая библиотечная функция ftok, которая образует ключ по указанному файлу.
Программа применяет ключ для создания объекта межпроцессного взаимодействия или получения доступа к существующему объекту. Обе операции вызываются при помощи операции get. Результатом операции get является его целочисленный идентификатор (facility identifier), который может использоваться при вызовах других процедур межпроцессного взаимодействия. Операция get похожа на вызов creat или open, а идентификатор средства межпроцессного взаимодействия ведет себя подобно дескриптору файла.
Есть еще два типа операций, которые применимы к средствам межпроцессного взаимодействия: операции управления, которые используются для опроса и изменения статуса объекта IPC, их функции выполняют вызовы msgctl, semctl и shmctl; операции, выполняющие основные функции IPC.
При создании объекта межпроцессного взаимодействия система также создает структуру статуса средства межпроцессного взаимодействия (IPC facility status structure), содержащую всю управляющую информацию, связанную с объектом. Для сообщений, семафоров и разделяемой памяти существуют разные типы структуры статуса.
uid_t uid; /*Действующий идентификатор пользователя*/
Права доступа определяют, может ли пользователь выполнять «чтение» из объекта (получать информацию о нем) или «запись» в объект (работать с ним). Коды прав доступа образуются точно таким же образом, как и для файлов. Права доступа, заданные элементом umode, применяются в сочетании с действующими идентификаторами пользователя и группы. Значение переменной umask пользователя не действует при создании средства межпроцессного взаимодействия.
Очереди сообщений
Сообщение является просто последовательностью символов или байтов (необязательно заканчивающейся нулевым символом). Сообщения передаются между процессами при помощи очередей сообщений (message queues), которые можно создавать или получать к ним доступ при помощи вызова msgget. После создания очереди процесс может помещать в нее сообщения при помощи вызова msgsnd, если он имеет соответствующие права доступа. Затем другой процесс может считать это сообщение при помощи примитива msgrcv, который извлекает сообщение из очереди.
Первый из вызовов, msgsnd, используется для добавления сообщения в очередь, обозначенную идентификатором mqid.
Для чтения из очереди, заданной идентификатором mqid, используется вызов msgrcv. Чтение разрешено, если процесс имеет права доступа к очереди на чтение. Успешное чтение сообщения приводит к удалению его из очереди.
Процедура msgctl служит трем целям: она позволяет процессу получать информацию о статусе очереди сообщений, изменять некоторые из связанных с очередью ограничений или удалять очередь из системы.
Семафоры
В информатике понятие семафор (semaphore) был впервые введено для решения задач синхронизации процессов. Семафор sem может рассматриваться как целочисленная переменная
Действия проверки и установки в обеих операциях должны составлять одно атомарное действие, чтобы только один процесс мог изменять семафор sem в каждый момент времени.
Семафоры могут использоваться несколькими способами. Наиболее простой из них заключается в обеспечении взаимного исключения (mutual exclusion), когда только один процесс может выполнять определенный участок кода одновременно.
Реализация семафоров в ОС UNIX основана на этой теоретической идее, хотя в действительности, предлагаемые средства являются более общими.
Вызов semget аналогичен вызову msgget. Дополнительный параметр nsems задает требуемое число семафоров в наборе семафоров. Это важный момент - семафорные операции в IPC приспособлены для работы с наборами семафоров, а не с отдельными объектами семафоров.
Значение, возвращаемое в результате успешного вызова semget, является идентификатором набора семафоров (semaphore set identifier), который ведет себя почти так же, как идентификатор очереди сообщений. Индекс семафора в наборе может принимать значения от 0 до (nsems-1).
С каждым семафором в наборе связаны следующие значения:
- semval - значение семафора, положительное целое число. Устанавливается при помощи системных вызовов работы с семафорами, то есть к значениям семафоров нельзя получить прямой доступ из программы, как к другим объектам данных;
- sempid - идентификатор процесса, который последним работал с семафором;
- semncnt - число процессов, ожидающих увеличения значения семафора;
- semzcnt - число процессов, ожидающих обнуления значения семафора.
Разделяемая память
Операции с разделяемой памятью позволяют двум и более процессам совместно использовать область физической памяти (общеизвестно, что обычно области данных любых двух программ совершенно отделены друг от друга). Чаще всего разделяемая память является наиболее производительным механизмом межпроцессного взаимодействия.
Для того чтобы сегмент памяти мог использоваться совместно, он должен быть сначала создан при помощи системного вызова shmget. После создания сегмента разделяемой памяти процесс может подключаться к нему при помощи вызова shmat и затем использовать его для своих частных целей. Когда этот сегмент памяти больше не нужен, процесс может отключиться от него при помощи вызова shmdt.
Сегменты разделяемой памяти создаются при помощи вызова shmget.