Способы межпроцессного обмена.
Традиционно считается, что основными способами межпроцессного обмена являются каналы и разделяемая память (рис. 7.1), которые базируются на соответствующих объектах ядра.
Рис. 7.1. Основные способы межпроцессного обмена
В случае разделяемой памяти два или более процессов совместно используют сегмент памяти. Общение происходит с помощью обычных операций копирования или перемещения данных в памяти (средствами обычных языков программирования).
Каналы предполагают созданные средствами операционной системы линии связи. Двумя основными моделями передачи данных по каналу являются поток ввода-вывода и сообщения. При передаче в рамках потоковой модели данные представляют собой неструктурированную последовательность байтов и никак не интерпретируются системой. В модели сообщений на передаваемые данные накладывается некоторая структура, обычно их разделяют на сообщения заранее оговоренного формата.
Понятие о разделяемом ресурсе
Межпроцессный обмен базируется на разделяемых ресурсах, к которым имеет доступ некоторое множество процессов (типичный пример работа системных функций SetLastError(), GetLasterror() ). При этом возникают задачи создания, именования и защиты таких ресурсов. Обычно один из процессов создает ресурс, наделяет его атрибутами защиты и именем, по которому данный ресурс может быть доступен остальным процессам (даже в случае завершения работы процесса-создателя).
В качестве примера рассмотрим общение через разделяемую память (рис. 7.2).
Рис. 7.2. Адресные пространства процессов, взаимодействующих через сегмент разделяемой памяти
В ОС Windows сегмент разделяемой памяти создается с помощью Win32-функции CreateFileMapping (см. рис. 7.3). В случае успешного выполнения данной функции создается ресурс - фрагмент памяти, доступный по имени (параметр lpname ), который базируется на соответствующем объекте ядра - "объекте-файле, отображаемом в память" с присущими любому объекту атрибутами. Процессу-создателю возвращается описатель (handle) ресурса. Другие процессы, желающие иметь доступ к ресурсу, также должны получить его описатель. В данном случае это можно сделать с помощью функции OpenFileMapping, указав имя ресурса в качестве одного из параметров.
Рис. 7.3. Создание сегмента разделяемой памяти базируется на разделяемом ресурсе, которому соответствует объект ядра
Каналы связи
Основной принцип работы канала состоит в буферизации вывода одного процесса и обеспечении возможности чтения содержимого программного канала другим процессом. При этом часто интерфейс программного канала совпадает с интерфейсом обычного файла и реализуется обычными файловыми операциями read и write. Для обмена могут использоваться потоковая модель и модель обмена сообщениями.
Механизм генерации канала предполагает получение процессом-создателем (процессом-сервером) двух описателей (handles) для пользования этим каналом. Один из описателей применяется для чтения из канала, другой - для записи в канал.
Один из вариантов использования канала - это его использование процессом для взаимодействия с самим собой. Рассмотрим следующее изображение системы, состоящей из процесса и ядра, после создания канала (рис. 7.5):
Рис. 7.5. Общение процесса с самим собой через канал связи
Из этого рисунка легко увидеть, что даже если процесс посылает данные самому себе, они проходят через ядро. Следовательно, для организации таких каналов, а также их именования, в ядре должны быть реализованы элементы файловой системы.
Обычно через канал взаимодействуют два (или более) процессов. Процесс, создающий канал, принято называть сервером, а другой процесс - клиентом. Для общения с каналом клиент и сервер должны иметь описатели (дескрипторы, handles) для чтения и записи. Процесс-сервер получает описатель при создании канала. Процесс-клиент может получить описатели в результате наследования, в том случае, когда клиент является потомком сервера. Это типично для общения через так называемые анонимные каналы. Другой способ получения - открытие по имени уже существующего именованного канала неродственным процессом, который в результате также становится обладателем необходимых описателей. Если организация доступа к каналу прошла успешно, то схема взаимодействия может выглядеть так, как показано на рис. 7.6.
Рис. 7.6. Общение процессов через канал связи
Если нужно организовать однонаправленную связь и принято решение о направлении передачи данных, то можно "закрыть" неиспользуемый конец канала. В примере на рис. 7.7 клиент посылает через канал информацию серверу.
Рис. 7.7. Передача информации от клиента серверу через канал связи