4.4. Двусторонние каналы

4.4. Двусторонние каналы

В предыдущем разделе мы отметили, что во многих системах реализованы двусторонние каналы. В Unix SVR4 это обеспечивается самой функцией pipe, а во многих других ядрах — функцией socketpair. Но что в действительности представляет собой двусторонний канал? Представим себе сначала однонаправленный канал, изображенный на рис. 4.8.

Рис. 4.8. Односторонний канал

Двусторонний канал мог бы быть реализован так, как это изображено на рис. 4.9. В этом случае неявно предполагается существование единственного буфера, в который помещается все, что записывается в канал (с любого конца, то есть дескриптора), и при чтении из канала данные просто считываются из буфера.

Рис. 4.9. Одна из возможных реализаций двустороннего канала (неправильная)

Такая реализация вызовет проблемы, например, в программе листинга А.14. Здесь требуется двусторонняя передача информации, причем потоки данных должны быть независимы. В противном случае некоторый процесс, записав данные в канал и перейдя затем в режим чтения из этого же канала, рискует считать обратно те же данные, которые были им только что туда записаны.

На рис. 4.10 изображена правильная реализация двустороннего канала.

Рис. 4.10. Правильная реализация двустороннего канала

Здесь двусторонний канал получается из объединения двух односторонних. Все данные, записываемые в fd[1], будут доступны для чтения из fd[0], а данные, записываемые в fd[0], будут доступны для чтения из fd[1].

Программа в листинге 4.4 иллюстрирует использование одного двустороннего канала для двусторонней передачи информации.

Листинг 4.4. Двусторонняя связь через двусторонний канал

//pipe/fduplex.c

1  #include "unpipc.h"

2  int

3  main(int argc, char **argv)

4  {

5   int fd[2], n;

6   char c;

7   pid_t childpid;

8   Pipe(fd); /* предполагается двусторонний канал (напр., SVR4) */

9   if ((childpid = Fork()) == 0) { /* child */

10   sleep(3):

11   if ((n = Read(fd[0], &c, 1)) != 1)

12    err_quit("child: read returned %d", n);

13   printf("child read %c ", c):

14   Write(fd[0], "c", 1);

15   exit(0);

16  }

17  /* родитель */

18  Write(fd[1], "p", 1);

19  if ((n = Read(fd[1], &c, 1)) != 1)

20   err_quit("parent: read returned %d", n):

21  printf("parent read %c ", c);

22  exit(0);

23 }

В этой программе сначала создается двусторонний канал, затем делается системный вызов fork. Породивший процесс записывает символ р в канал, а затем считывает из канала данные. Дочерний процесс ждет три секунды, считывает символ из канала, а потом записывает туда символ с. Задержка чтения для дочернего процесса позволяет породившему процессу вызвать read первым — таким образом мы можем узнать, не будет ли им считан обратно только что записанный символ.

При запуске этой программы в Solaris 2.6, в которой организована поддержка двусторонних каналов, мы получим ожидаемый результат:

solaris % fduplex

child read p

parent read с

Символ р передается по одному из двух односторонних каналов, изображенных на рис. 4.10, а именно по верхнему каналу. Символ с передается по нижнему одностороннему каналу. Родительский процесс не считывает обратно записанный им в канал символ р (что и требуется).

При запуске этой программы в Digital Unix 4.0B, в которой по умолчанию создаются односторонние каналы (двусторонние каналы — как в SVR4 — будут создаваться в том случае, если при компиляции указать специальные параметры), мы увидим результат, ожидаемый для одностороннего канала:

alpha % fduplex

read error: Bad file number

alpha % child read p

write error: Bad file number

Родительский процесс записывает символ р, который успешно считывается дочерним процессом, однако при попытке считывания из канала (дескриптор fd[l]) родительский процесс прерывается с ошибкой, как и дочерний процесс, при попытке записи в канал (дескриптор fd[0]). Вспомните рис. 4.8. Функция read возвращает код ошибки EBADF, означающий, что дескриптор не открыт для чтения. Аналогично write возвращает тот же код ошибки, если дескриптор не был открыт на запись.

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

5.12 КАНАЛЫ

Из книги Архитектура операционной системы UNIX автора Бах Морис Дж

5.12 КАНАЛЫ Каналы позволяют передавать данные между процессами в порядке поступления («первым пришел — первым вышел»), а также синхронизировать выполнение процессов. Их использование дает процессам возможность взаимодействовать между собой, пусть даже не известно,


Каналы

Из книги Язык программирования С# 2005 и платформа .NET 2.0. [3-е издание] автора Троелсен Эндрю

Каналы После того как агенты проверят и отформатируют поставляемые клиентом аргументы, упаковав их в объект сообщении, соответствующий IMessage-совместимый тип передается от реального агента объекту канала. Каналы – это сущности, отвечающие за транспортировку сообщения


Каналы RGB

Из книги Photoshop. Мультимедийный курс автора Мединов Олег

Каналы RGB Проведем простой эксперимент.1. Создайте новое изображение с белым фоном.2. Выберите инструмент Карандаш. Настройте кисть таким образом, чтобы линия карандаша получилась достаточно жирной, например 50 пикселов.3. Выберите чисто красный цвет. Для этого в диалоговом


Каналы IRC

Из книги Asterisk™: будущее телефонии Второе издание автора Меггелен Джим Ван

Каналы IRC Сообщество разработчиков Asterisk поддерживает каналы ретрансляции интернет-чатов (Internet Relay Chat, IRC) на сайте irc.freenode.net. Самыми активными каналами являются #asterisk и #asterisk-dev[9]. В целях защиты от спама теперь на обоих каналах требуется


Каналы FXO и FXS

Из книги Системное программирование в среде Windows автора Харт Джонсон М

Каналы FXO и FXS Каналы FXO и FXS отличаются друг от друга лишь тем, что один из них обеспечивает тональный сигнал готовности линии. FXO-порт не генерирует тонального сигнала, он его принимает. Самый простой пример - тональный сигнал, поставляемый телефонной компанией. FXS- порт


Анонимные каналы

Из книги Программирование на языке Ruby [Идеология языка, теория и практика применения] автора Фултон Хэл

Анонимные каналы Анонимные каналы (anonymous channels) Windows обеспечивают однонаправленное (полудуплексное) посимвольное межпроцессное взаимодействие. Каждый канал имеет два дескриптора: дескриптор чтения (read handle) и дескриптор записи (write handle). Функция, с помощью которой создаются


10.1.13. Каналы

Из книги Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ автора Борри Хелен


22.5. Каналы IRC

Из книги Photoshop CS4 автора Жвалевский Андрей Валентинович

22.5. Каналы IRC Можно побиться об заклад, что в любое время суток десятки «рубистов» болтают в IRC-чатах. Такие серверы принадлежат freenode.net; зайдите на этот сайт и поищите ближайший к вам. Поиск в Web поможет вам найти подходящий IRC-клиент для любой платформы.В канале #ruby-lang


Именованные каналы

Из книги Linux программирование в примерах автора Роббинс Арнольд

Именованные каналы Firebird поддерживает протокол Мiсrоsоft WNet Named Pipes для серверов Windows NT/2000, XP и клиентов Windows. Имя канала по умолчанию interbas. Windows 9х и ME не Moryт быть серверами WNet.! ! !ПРИМЕЧАНИЕ. Протокол Windows Named Pipes (именованные каналы) часто называют NetBEUI. Строго говоря, NetBEUI является


Каналы

Из книги Программирование для Linux. Профессиональный подход автора Митчелл Марк

Каналы Чтобы нарисовать картину, художники используют палитру, смешивая на ней краски. Благодаря этому они получают любые оттенки цветов. В Photoshop для передачи цвета также применяются методы смешения цветов. При этом используется одна из двух основных палитр:• RGB –


9.3.1. Каналы

Из книги Операционная система UNIX автора Робачевский Андрей М.


5.4. Каналы

Из книги автора

5.4. Каналы Канал — это коммуникационное устройство, допускающее однонаправленное взаимодействие. Данные, записываемые на "входном" конце канала, читаются на "выходном" его конце. Каналы являются последовательными устройствами: данные всегда читаются в том порядке, в


5.4.5. Каналы FIFO

Из книги автора

5.4.5. Каналы FIFO Файл FIFO (First-In, First-Out — первым пришел, первым обслужен) — это канал, у которого есть имя в файловой системе. Любой процесс может открыть и закрыть такой файл. Процессы, находящиеся на противоположных концах канала, не обязаны быть связанными друг с другом.


Каналы

Из книги автора

Каналы Вспомните синтаксис организации программных каналов при работе в командной строке shell:cat myfile | wcПри этом (стандартный) вывод программы cat(1), которая выводит содержимое файла myfile, передается на (стандартный) ввод программы wc(1), которая, в свою очередь подсчитывает