Главная страница Взаимодействие нетривиальных процессов ГЛАВА 4 Именованные и неименованные каналы 4.1. Введение Неименованные каналы - это самая первая форма IPC в Unix, появившаяся еще в 1973 году в третьей версии (Third Edition [17]). Несмотря на полезность во многих случаях, главным недостатком неименованных каналов является отсутствие имени, вследствие чего они могут использоваться для взаимодействия только родственными процессами. Это было исправлено в Unix System III (1982) добавлением каналов FIFO, которые иногда называются именованными каналами. Доступ и к именованным каналам, и к неименованным организуется с помощью обычных функций read и write. ПРИМЕЧАНИЕ- Программные (неименованные) каналы в принципе могут использоваться неродственными процессами, если предоставить им возможность передавать друг другу дескрипторы (см. раздел 15.8 этой книги или раздел 13.7 [24]). Однако на практике эти каналы обычно используются для осуществления взаимодействия между процессами, у которых есть общий предок. В этой главе описываются детали, касающиеся создания и использования программных каналов и каналов FIFO. Мы рассмотрим пример простейшего сервера файлов, а также обратим внимание на некоторые детали модели клиент-сервер, в частности постараемся определить количество требуемых каналов IPC, сравним последовательные серверы с параллельными и неструктурированные потоки байтов с сообщениями. 4.2. Приложение типа клиент-сервер Пример приложения модели клиент-сервер приведен на рис. 4.1. Именно на него мы будем ссылаться в тексте этой главы и главы 6 при необходимости проиллюстрировать использование программных каналов, FIFO и очередей сообщений System V. Клиент считывает полное имя (файла) из стандартного потока ввода и записывает его в канал IPC. Сервер считывает это имя из канала IPC и производит попытку открытия файла на чтение. Если попытка оказывается успешной, сервер
сервер файл путь содержимое файла или сообщение об ошибке Рис. 4.1. Пример приложения типа клиент-сервер 4.3. Программные каналы Программные каналы имеются во всех существующих реализациях и версиях Unix, Канал создается вызовом pipe и предоставляет возможность однонаправленной (односторонней) передачи данных: finclude <unistd.h> int pipeCint fd[2]); /* возвращает О в случае успешного завершения, -1 - в случае ошибки;*/ Функция возвращает два файловых дескриптора: fd[0] и fd[l], причем первый открыт для чтения, а второй - для записи. ПРИМЕЧАНИЕ-- Некоторые версии Unix, в частности SVR4, поддерживают двусторонние канааы (full-duplex pipes). В этом случае канаа открыт на запись и чтение с обоих концов. Другой способ создания двустороннего канааа IPC заключается в вызове функции socketpair, описанной в разделе 14.3 [24]. Его можно использовать в большинстве современных версий Unix. Однако чаще всего канааы используются при работе с интерпретатором команд, где уместно использование именно односторонних канааов. Стандарты Posix. 1 и Unix 98 требуют только односторонних канааов, и мы будем исходить из этого. Для определения типа дескриптора (файла, программного канала или FIFO) можно использовать макрос S ISFI FO. Он принимает единственный аргумент: поле st mode структуры stat и возвращает значение истина (ненулевое значение) или ложь (ноль). Структуру stat для канала возвращает функция fstat. Для FIFO структура возвращается функциями fstat, 1 stat и stat. , На рис. 4.2 изображен канал при использовании его единственным процессом. Хотя канал создается одним процессом, он редко используется только этим процессом (пример канала в одиночном процессе приведен в листинге 5.12). Каналы обычно используются для связи между двумя процессами (родительским и дочерним) следующим образом: процесс создает канал, а затем вызывает fork, создавая свою копию - дочерний процесс (рис. 4.3). Затем родительский про- считывает файл и записывает его в канал IPC. В противном случае сервер возвращает клиенту сообщение об ощибке. Клиент считывает данные из канала IPC и записывает их в стандартный поток вывода. Если сервер не может считать файл, из канала будет считано сообщение об ощибке. В противном случае будет принято содержимое файла. Две штриховые линии между клиентом и сервером на рис. 4.1 представляют собой канал IPC. процесс -> поток данных -> Рис. 4.2. Канал в одиночном процессе родительский процесс fork дочерний процесс
-> поток данных -Рис. 4.3. Канал после вызова fork родительский процесс дочерний процесс
-> поток данных -> Рис. 4.4. Канал межцу двумя процессами цесс закрывает открытый для чтения конец канала, а дочерний, в свою очередь, - открытый на запись конец канала. Это обеспечивает одностороннюю передачу данных между процессами, как показано на рис. 4.4.
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |