- Способ передачи данных между процессами
- Создание канала Mailslot
- Открытие канала Mailslot
- Запись сообщений в канал Mailslot
- Чтение сообщений из канала Mailslot
- Определение состояния канала Mailslot
- Изменение состояния канала Mailslot
- Примеры приложений
- Приложение MSLOTS
- Приложение MSLOTС
- Обмен данными между процессами
- Использование буфера обмена для IPC
- Использование COM для IPC
- Использование копирования данных для IPC
- Использование DDE для IPC
- Использование сопоставления файлов для IPC
- Использование слота для IPC
- Использование каналов для IPC
- Использование RPC для IPC
- использование сокетов Windows для IPC
Способ передачи данных между процессами
В завершении этой главы мы рассмотрим еще один простой способ организации передачи данных между различными процессами, основанный на использовании датаграммных каналов Mailslot.
Каналы Mailslot позволяют выполнять одностороннюю передачу данных от одного или нескольких клиентов к одному или нескольким серверам. Главная особенность каналов Mailslot заключается в том, что они, в отличие от других средств, рассмотренных нами в этой главе, позволяют передавать данные в широковещательном режиме.
Это означает, что на компьютере или в сети могут работать несколько серверных процессов, способных получать сообщения через каналы Mailslot. При этом один клиентский процесс может посылать сообщения сразу всем этим серверным процессам.
С помощью каналов Pipe вы не сможете передавать данные в широковещательном режиме, так как только два процесса могут создать канал типа Pipe.
Создание канала Mailslot
Канал Mailslot создается серверным процессом с помощью специально предназначенной для этого функции CreateMailslot, которую мы рассмотрим немного позже. После создания серверный процесс получает идентификатор канала Mailslot. Пользуясь этим идентификатором, сервер может читать сообщения, посылаемые в канал клиентскими процессами. Однако сервер не может выполнять над каналом Mailslot операцию записи, так как этот канал предназначен только для односторонней передачи данных — от клиента к серверу.
Приведем прототип функции CreateMailslot:
Через параметр lpName вы должны передать функции CreateMailslot адрес строки символов с именем канала Mailslot. Эта строка имеет следующий вид:
В этом имени путь является необязательной компонентой. Тем не менее, вы можете указать его аналогично тому, как это делается для файлов. Что же касается имени канала Mailslot, то оно задается аналогично имени канала Pipes.
Параметр nMaxMsgSize определяет максимальный размер сообщений, передаваемых через создаваемый канал Mailslot. Вы можете указать здесь нулевое значение, при этом размер сообщений не будет ограничен. Есть, однако, одно исключение — размер широковещательных сообщений, передаваемых всем рабочим станциям и серверам домена не должен превышать 400 байт.
С помощью параметра lReadTimeout серверное приложение может задать время ожидания для операции чтения в миллисекундах, по истечении которого функция чтения вернет код ошибки. Если вы укажите в этом параметре значение MAILSLOT_WAIT_FOREVER, ожидание будет бесконечным.
Параметр lpSecurityAttributes задает адрес структуры защиты, который мы в наших приложениях будем указывать как NULL.
При ошибке функцией CreateMailslot возвращается значение INVALID_HANDLE_VALUE. Код ошибки можно определить при помощи функции GetLastError.
Ниже мы привели пример использования функции CreateMailslot в серверном приложении:
В этом примере мы задали максимальный размер сообщения, поэтому на эту величину нет ограничений (кроме ограничения в 400 байт для сообщений, передаваемых всем компьютерам домена в широковещательном режиме).
Время ожидания указано как MAILSLOT_WAIT_FOREVER, поэтому функции, работающие с данным каналом Mailslot, будут работать в блокирующем режиме.
Открытие канала Mailslot
Прежде чем приступить к работе с каналом Mailslot, клиентский процесс должен его открыть. Для выполнения этой операции следует использовать функцию CreateFile, например, так:
Здесь в качестве первого параметра функции CreateFile передается имя канала Mailslot. Заметим, что вы можете открыть канал Mailslot, созданный на другой рабочей станции в сети. Для этого строка имени канала, передаваемая функции CreateFile, должна иметь следующий вид:
Можно открыть канал для передачи сообщений всем рабочим станциям заданного домена. Для этого необходимо задать имя по следующему образцу:
Для передачи сообщений одновременно всем рабочим станциям сети первичного домена имя задается следующим образом:
В качестве второго параметра функции CreateFile мы передаем константу GENERIC_WRITE. Эта константа определяет, что над открываемым каналом будет выполняться операция записи. Напомним, что клиентский процесс может только посылать сообщения в канал Mailslot, но не читать их оттуда. Чтение сообщений из канала Mailslot — задача для серверного процесса.
Третий параметр указан как FILE_SHARE_READ, и это тоже необходимо, так как сервер может читать сообщения, посылаемые одновременно несколькими клиентскими процессами.
Обратите также внимание на константу OPEN_EXISTING. Она используется потому, что функция CreateFile открывает существующий канал, а не создает новый.
Запись сообщений в канал Mailslot
Запись сообщений в канал Mailslot выполняет клиентский процесс, вызывая для этого функцию WriteFile. С этой функцией вы уже имели дело:
В качестве первого параметра этой функции необходимо передать идентификатор канала Mailslot, полученный от функции CreateFile.
Второй параметр определяет адрес буфера с сообщением, третий — размер сообщения. В нашем случае сообщения передаются в виде текстовой строки, закрытой двоичным нулем, поэтому для определения длины сообщения мы воспользовались функцией strlen.
Чтение сообщений из канала Mailslot
Серверный процесс может читать сообщения из созданного им канала Mailslot при помощи функции ReadFile, как это показано ниже:
Через первый параметр функции ReadFile передается идентификатор созданного ранее канала Mailslot, полученный от функции CreateMailslot. Второй и третий параметры задают, соответственно, адрес буфера для сообщения и его размер.
Заметим, что перед выполнением операции чтения следует проверить состояние канала Mailslot. Если в нем нет сообщений, то функцию ReadFile вызывать не следует. Для проверки состояния канала вы должны воспользоваться функцией GetMailslotInfo, описанной ниже.
Определение состояния канала Mailslot
Серверный процесс может определить текущее состояние канала Mailslot по его идентификатору с помощью функции GetMailslotInfo. Прототип этой функции мы привели ниже:
Через параметр hMailslot функции передается идентификатор канала Mailslot, состояние которого необходимо определить.
Остальные параметры задаются как указатели на переменные типа DWORD, в которые будут записаны параметры состояния канала Mailslot.
В переменную, адрес которой передается через параметр lpMaxMessageSize, после возвращения из функции GetMailslotInfo будет записан максимальный размер сообщения. Вы можете использовать это значение для динамического получения буфера памяти, в который это сообщение будет прочитано функцией ReadFile.
В переменную, адрес которой указан через параметр lpNextSize, записывается размер следующего сообщения, если оно есть в канале. Если же в канале больше нет сообщений, в эту переменную будет записана константа MAILSLOT_NO_MESSAGE.
С помощью параметра lpMessageCount вы можете определить количество сообщений, записанных в канал клиентскими процессами. Если это количество равно нулю, вам не следует вызывать функцию ReadFile для чтения несуществующего сообщения.
И, наконец, в переменную, адрес которой задается в параметре lpReadTimeout, записывается текущее время ожидания, установленное для канала (в миллисекундах).
Если вам не нужна вся информация, которую можно получить с помощью функции GetMailslotInfo, некоторые из ее параметров (кроме, разумеется, первого) можно указать как NULL.
В случае успешного завершения функция GetMailslotInfo возвращает значение TRUE, а при ошибке — FALSE. Код ошибки можно получить, вызвав функцию GetLastError.
Ниже мы привели пример использоания функции GetMailslotInfo:
Изменение состояния канала Mailslot
С помощью функции SetMailslotInfo серверный процесс может изменить время ожидания для канала Mailslot уеж после его создания.
Прототип функции SetMailslotInfo приведен ниже:
Через параметр hMailslot функции SetMailslotInfo передается идентификатор канала Mailslot, для которого нужно изменить время ожидания.
Новое значение времени ожидания в миллисекундах задается через параметр dwReadTimeout. Вы также можете указать здесь константы 0 или MAILSLOT_WAIT_FOREVER. В первом случае функции, работающие с каналом, вернут управление немедленно, во втором — будут находиться в состоянии ожидания до тех пор, пока не завершится выполняемая операция.
Примеры приложений
Для примера мы подготовили исходные тексты двух приложений — MSLOTS и MSLOTC, которые обмениваются информацией через канал Mailslot (рис. 2.6).
Рис. 2.6. Обмен сообщениями между приложениями MSLOTS и MSLOTC
Приложение MSLOTS выполняет роль сервера, создавая канал Mailslot. Периодически с интервалом 0,5 с это приложение проверяет, не появилось ли в канале сообщение. Если появилось, это сообщение отображается в консольном окне.
Клиентское приложение MSLOTC устанавливает связь с приложением MSLOTS. Если при запуске указать имя компьютера или домена, возможно подключение к серверу MSLOTS, запущенному на другой рабочей станции в сети.
Если вводить текстовые строки в приглашении cmd>, которое выводится в консольном окне клиентского приложения MSLOTC, они будут передаваться серверу через канал Mailslot и отображаться в его окне. Для завершения работы обоих приложений вы должны ввести в приглашении клиента команду exit.
Перейдем теперь к описанию исходных текстов наших приложений.
Приложение MSLOTS
Исходный текст серверного приложения MSLOTS представлен в листинге 2.13.
Листинг 2.13. Файл mailslot/mslots/mslots.c
Прежде всего, серверное приложение создает канал Mailslot, пользуясь для этого функцией CreateMailslot:
Далее запускается цикл, в котором после определения состояния канала выполняется чтение сообщений из него (при условии, что в канале есть сообщения). Для проверки состояния канала мы используем функцию GetMailslotInfo.
Сообщение читается функцией ReadFile:
После чтения перед выполнением очередной проверки состояния приложение выполняет задержку, вызывая для этого функцию Sleep:
Задержка необходима для того, чтобы ожидание сообщения в цикле не отнимало слишком много системных ресурсов у других приложений.
Перед завершением работы приложения мы закрываем идентификатор канала Mailslotс помощью функции CloseHandle:
Приложение MSLOTС
Исходный текст клиентского приложения MSLOTC представлен в листинге 2.14.
Листинг 2.14. Файл mailslot/mslotc/mslotc.c
Сразу после запуска приложение проверяет параметры. Если вы указали имя компьютера или домена,оно будет вставлено в строку, передаваемую функции CreateFile, открывающей канал Mailslot.
Канал открывается следующим образом:
В результате будет открыт канал, предназначенный для записи в синхронном режиме.
Ввод и передача текстовых строк через канал выполняется в цикле, не имеющем никаких особенностей. Для записи введенной строки в канал мы вызываем функцию WriteFile:
Перед завершением своей работы приложение MSLOTC закрывает канал, вызывая для этого функцию CloseHandle XE.
Источник
Обмен данными между процессами
операционная система Windows предоставляет механизмы для облегчения обмена данными и совместного использования данных между приложениями. В совокупности действия, которые поддерживаются этими механизмами, называются взаимосвязями (IPC). Некоторые формы IPC упрощают разделение труда между несколькими специализированными процессами. Другие формы IPC облегчают разделение труда между компьютерами в сети.
Как правило, приложения могут использовать IPC категории «клиенты» или «серверы». Клиент — это приложение или процесс, запрашивающий службу от какого-либо другого приложения или процесса. Сервер — это приложение или процесс, отвечающий на запрос клиента. Многие приложения действуют как клиент и сервер в зависимости от ситуации. Например, приложение для обработки текстов может выступать в качестве клиента в запросе сводной таблицы производственных затрат из приложения электронной таблицы, выступающего в качестве сервера. Приложение электронной таблицы, в свою очередь, может работать в качестве клиента при запросе последних уровней инвентаризации от приложения управления инвентаризацией.
После принятия решения о том, что приложение будет выгодным из IPC, необходимо решить, какой из доступных методов IPC использовать. Скорее всего, приложение будет использовать несколько механизмов IPC. Ответы на эти вопросы определяют, может ли приложение использовать преимущества одного или нескольких механизмов IPC.
- Должно ли приложение взаимодействовать с другими приложениями, работающими на других компьютерах в сети, или достаточно для того, чтобы приложение могло обмениваться данными только с приложениями на локальном компьютере?
- должно ли приложение взаимодействовать с приложениями, работающими на других компьютерах, которые могут работать под управлением разных операционных систем (например, 16-разрядные Windows или UNIX)?
- Следует ли пользователю приложения выбрать другие приложения, с которыми взаимодействует приложение, или может ли приложение неявным образом найти своих взаимодействующих партнеров?
- Следует ли, чтобы приложение взаимодействовало со многими различными приложениями обычным образом, например разрешить операции вырезания и вставки с любым другим приложением или должны ли требования к обмену информацией ограничиваться ограниченным набором взаимодействий с конкретными другими приложениями?
- Является ли производительность критически важным аспектом приложения? Все механизмы IPC включают некоторый объем издержек.
- Должно ли приложение быть приложением с графическим интерфейсом или консольным приложением? Для некоторых механизмов IPC требуется приложение с графическим пользовательским интерфейсом.
Windows поддерживает следующие механизмы IPC:
Использование буфера обмена для IPC
Буфер обмена выступает в качестве центрального депозита для совместного использования данных между приложениями. Когда пользователь выполняет операцию вырезания или копирования в приложении, приложение помещает выбранные данные в буфер обмена в одном или нескольких стандартных или определенных форматах приложения. Затем любое другое приложение может получить данные из буфера обмена, выбрав из доступных форматов, которые он понимает. Буфер обмена — это очень слабо связанный носитель Exchange, где приложения должны быть согласованы только с форматом данных. Приложения могут находиться на одном компьютере или на разных компьютерах в сети.
Ключевой момент: Все приложения должны поддерживать буфер обмена для тех форматов данных, которые они понимают. Например, текстовый редактор или текстовый процессор должен иметь по крайней мере возможность создавать и принимать данные из буфера обмена в формате чистого текста. Дополнительные сведения см. в разделе буфер обмена.
Использование COM для IPC
Приложения, использующие OLE для управления составными документами, то есть документы, состоящие из данных различных приложений. OLE предоставляет службы, облегчающие приложениям вызов в других приложениях для редактирования данных. Например, текстовый процессор, использующий OLE, может внедрить граф из электронной таблицы. Пользователь может автоматически запустить электронную таблицу с помощью текстового процессора, выбрав внедренную диаграмму для редактирования. OLE берет на себя запуск электронной таблицы и представление графа для редактирования. Когда пользователь закрывает электронную таблицу, диаграмма будет обновлена в исходном документе текстового процессора. Электронная таблица является расширением текстового процессора.
Основой OLE является объектная модель компонента (COM). Программный компонент, использующий COM, может взаимодействовать с множеством других компонентов, даже если они еще не были написаны. Компоненты взаимодействуют как объекты и клиенты. Распределенная модель COM расширяет модели программирования COM таким образом, чтобы она работала по сети.
Ключевой момент: OLE поддерживает составные документы и позволяет приложению включать внедренные или связанные данные, которые при выборе автоматически запускают другое приложение для редактирования данных. Это позволяет расширить приложение с помощью любого другого приложения, использующего OLE. Объекты COM предоставляют доступ к данным объекта через один или несколько наборов связанных функций, известных как интерфейсы. дополнительные сведения см. в разделе COM и ActiveX службы объектов.
Использование копирования данных для IPC
Копирование данных позволяет приложению передавать данные в другое приложение с помощью сообщения WM _ COPYDATA . Этот метод требует взаимодействия между отправляющим приложением и принимающим приложением. Принимающее приложение должно знать формат информации и уметь определять отправителя. Отправляющее приложение не может изменять память, на которую ссылаются указатели.
Ключевой момент: копирование данных можно использовать для быстрой отправки сведений в другое приложение с помощью Windows messaging. Дополнительные сведения см. в разделе копирование данных.
Использование DDE для IPC
DDE — это протокол, позволяющий приложениям обмениваться данными в различных форматах. Приложения могут использовать DDE для одноразовых обменов данными или для текущих обменов, в которых приложения обновляются по мере появления новых данных.
Форматы данных, используемые DDE, совпадают с форматами, используемыми в буфере обмена. DDE можно рассматривать как расширение механизма буфера обмена. Буфер обмена почти всегда используется для одноразового ответа на пользовательскую команду, например для выбора команды вставить в меню. DDE также обычно инициируется пользователем с помощью пользовательской команды, но часто остается без вмешательства пользователя. Кроме того, можно определить пользовательские форматы данных DDE для особого целевого IPC между приложениями с более тесно связанными требованиями к обмену данными.
Обмен DDE может происходить между приложениями, запущенными на одном компьютере, или на разных компьютерах в сети.
Ключевой момент: DDE не так эффективнее, как новые технологии. Тем не менее можно по-прежнему использовать DDE, если другие механизмы IPC не подходят или если необходимо взаимодействовать с существующим приложением, которое поддерживает только DDE. дополнительные сведения см. в разделе платформа динамических данных Exchange и платформа динамических данных библиотеки управления Exchange.
Использование сопоставления файлов для IPC
Сопоставление файлов позволяет процессу обрабатывать содержимое файла так, будто он был блоком памяти в адресном пространстве процесса. Процесс может использовать простые операции с указателями для проверки и изменения содержимого файла. Когда двум или более процессам выполняется доступ к одному сопоставлению файлов, каждый процесс получает указатель на память в своем собственном адресном пространстве, который может использоваться для чтения или изменения содержимого файла. Для предотвращения повреждения данных в многозадачной среде процессы должны использовать объект синхронизации, например семафор.
Для предоставления именованной общей памяти между процессами можно использовать особый вариант сопоставления файлов. При указании файла подкачки системы при создании объекта сопоставления файлов объект сопоставления файлов рассматривается как блок общей памяти. Другие процессы могут получить доступ к тому же блоку памяти, открыв тот же объект сопоставления файлов.
Сопоставление файлов является довольно эффективным, а также предоставляет поддерживаемые атрибуты безопасности операционной системы, которые могут помочь предотвратить несанкционированный повреждение данных. Сопоставление файлов может использоваться только между процессами на локальном компьютере. его нельзя использовать по сети.
Ключевой момент: Сопоставление файлов является эффективным способом для двух или более процессов на одном компьютере для совместного использования данных, но необходимо обеспечить синхронизацию между процессами. Дополнительные сведения см. в разделе Сопоставление файлов и Синхронизация.
Использование слота для IPC
Маилслотс обеспечивают односторонний обмен данными. Любой процесс, создающий почтовый слот, — это сервер слота сообщений. Другие процессы, называемые клиентами слота, отправляют сообщения на сервер слота, записывая сообщение в почтовый слот. Входящие сообщения всегда добавляются в почтовый слот. Почтовый слот сохраняет сообщения до тех пор, пока сервер слота не прочитает их. Процесс может быть как сервером слота, так и клиентом слота, поэтому двустороннее взаимодействие возможно с помощью нескольких маилслотс.
Клиент слота сообщений может отправить сообщение в почтовый слот на локальном компьютере, в почтовый слот другого компьютера или на все маилслотс с тем же именем на всех компьютерах в указанном сетевом домене. Сообщения, передаваемые во все маилслотс в домене, не могут быть длиннее 400 байт, а сообщения, отправляемые в один почтовый слот, ограничиваются только максимальным размером сообщения, указанным сервером слота при создании слота.
Ключевой момент: Маилслотс предлагают пользователям простой способ отправки и получения коротких сообщений. Они также предоставляют возможность рассылать сообщения между всеми компьютерами в сетевом домене. Дополнительные сведения см. в разделе маилслотс.
Использование каналов для IPC
Существует два типа каналов для двусторонней связи: анонимные каналы и именованные каналы. Анонимные каналы позволяют связанным процессам передавать данные друг другу. Как правило, анонимный канал используется для перенаправления стандартного ввода или вывода дочернего процесса, чтобы он мог обмениваться данными с родительским процессом. Для обмена данными в обоих направлениях (дуплексная операция) необходимо создать два анонимных канала. Родительский процесс записывает данные в один канал, используя его маркер записи, в то время как дочерний процесс считывает данные из этого канала, используя его маркер чтения. Аналогичным образом дочерний процесс записывает данные в другой канал, а родительский процесс считывает из него. Анонимные каналы не могут использоваться по сети и не могут использоваться между несвязанными процессами.
Именованные каналы используются для обмена данными между процессами, которые не являются связанными процессами и между процессами на разных компьютерах. Как правило, серверный процесс именованного канала создает именованный канал с известным именем или именем, которое должно обмениваться с клиентами. Клиентский процесс именованного канала, который знает имя канала, может открыть его другой конец с учетом ограничений доступа, заданных процессом сервера именованных каналов. После того как сервер и клиент подключены к каналу, они могут обмениваться данными, выполняя операции чтения и записи в канале.
Ключевой момент: Анонимные каналы предоставляют эффективный способ перенаправлять стандартные входные или выходные данные в дочерние процессы на том же компьютере. Именованные каналы предоставляют простой программный интерфейс для передачи данных между двумя процессами независимо от того, находятся ли они на одном компьютере или по сети. Дополнительные сведения см. в разделе каналы.
Использование RPC для IPC
RPC позволяет приложениям вызывать функции удаленно. Таким образом, RPC делает IPC проще, чем вызов функции. RPC работает между процессами на одном компьютере или на разных компьютерах в сети.
RPC, предоставляемый Windows, соответствует требованиям к распределенным вычислительным средам (использование) Open Software Foundation (DCE). Это означает, что приложения, использующие RPC, могут взаимодействовать с приложениями, работающими с другими операционными системами, поддерживающими DCE. RPC автоматически поддерживает преобразование данных для учета различных архитектур оборудования и для упорядочения байтов между разнородными средами.
Клиенты и серверы RPC тесно связаны, но по-прежнему поддерживают высокую производительность. Система активно использует RPC для упрощения связи между клиентом и сервером между различными частями операционной системы.
Ключевой момент: RPC — это интерфейс уровня функции с поддержкой автоматического преобразования данных и взаимодействия с другими операционными системами. С помощью RPC можно создавать высокопроизводительные распределенные приложения с высоким уровнем производительности. Дополнительные сведения см. в разделе компоненты Microsoft RPC.
использование сокетов Windows для IPC
Windows Сокеты — это независимый от протокола интерфейс. В нем используются возможности связи базовых протоколов. в сокетах Windows 2 при необходимости можно использовать обработчик сокетов в качестве файла с стандартными функциями файлового ввода-вывода.
Windows Сокеты основаны на гнездах, которые впервые популярны по Berkeley Software Distribution (BSD). приложение, которое использует сокеты Windows, может взаимодействовать с другой реализацией сокета в других типах систем. Однако не все поставщики транспортных служб поддерживают все доступные варианты.
ключевой момент: Windows сокеты — это независимый от протокола интерфейс, поддерживающий текущие и новые сетевые возможности. дополнительные сведения см. в разделе сокеты Windows 2.
Источник