Чтение онлайн

на главную - закладки

Жанры

Linux программирование в примерах

Роббинс Арнольд

Шрифт:

Как упоминалось, данные, записанные в записываемый конец, считываются из читаемого конца. После завершения работы с каналом оба конца закрываются с помощью вызова

close
. Следующая простая программа,
ch09-pipedemo.c
, демонстрирует каналы путем создания канала, записи в него данных, а затем чтения этих данных из него:

1 /* ch09-pipedemo.c --- демонстрация ввода/вывода с каналом. */

2

3 #include <stdio.h>

4 #include <errno.h>

5 #include <unistd.h>

6

7 /* main --- создание канала, запись в него и чтение из него. */

8

9 int main(int argc, char **argv)

10 {

11 static const char mesg[] = "Don't Panic!"; /* известное сообщение */

12 char buf[BUFSIZ];

13 ssize_t rcount, wcount;

14 int pipefd[2];

15 size_t l;

16

17 if (pipe(pipefd) < 0) {

18 fprintf(stderr, "%s: pipe failed: %s\n", argv[0],

19 strerror(errno));

20 exit(1);

21 }

22

23 printf("Read end = fd %d, write end = fd %d\n",

24 pipefd[0], pipefd[1]);

25

26 l = strlen(mesg);

27 if ((wcount = write(pipefd[1], mesg, 1)) != 1) {

28 fprintf(stderr, "%s: write failed: %s\n", argv[0],

29 strerror(errno));

30 exit(1);

31 }

32

33 if ((rcount = read(pipefd[0], buf, BUFSIZ)) != wcount) {

34 fprintf(stderr, "%s: read failed: %s\n", argv[0],

35 strerror(errno));

36 exit(1);

37 }

38

39 buf[rcount] = '\0';

40

41 printf("Read <%s> from pipe\n", buf);

42 (void)close(pipefd[0]);

43 (void)close(pipefd[1]);

44

45 return 0;

46 }

Строки 11–15 объявляют локальные переменные; наибольший интерес представляет

mesg
, который представляет текст, проходящий по каналу.

Строки 17–21 создают канал с проверкой ошибок; строки 23–24 выводят значения новых дескрипторов файлов (просто для подтверждения, что они не равны 0, 1 или 2)

В строке 26 получают длину сообщения для использования с

write
. Строки 27–31 записывают сообщение в канал, снова с проверкой ошибок.

Строки 33–37 считывают содержимое канала, опять с проверкой ошибок. Строка 39 предоставляет завершающий нулевой байт, так что прочитанные данные могут использоваться в качестве обычной строки. Строка 41 выводит данные, а строки 42–43 закрывают оба конца канала. Вот что происходит при запуске программы:

$ ch09-pipedemo

Read end = fd 3, write end = fd 4

Read <Don't Panic!> from pipe

Эта программа не делает ничего полезного, но она демонстрирует основы. Обратите внимание, что нет вызовов

open
или
creat
и что программа не использует три своих унаследованных дескриптора. Тем не менее,
write
и
read
завершаются успешно, показывая, что дескрипторы файлов действительны и что данные, поступающие в канал, действительно выходят из него. [95] Конечно, будь сообщение слишком большим, наша программа не работала бы. Это происходит из-за того, что размер (памяти) каналов ограничен, факт, который мы обсудим в следующем разделе.

95

Мы уверены, что вы не волновались. В конце концов, вы, возможно, используете конвейеры из оболочки десятки раз в день — Примеч. автора.

Подобно другим дескрипторам файлов, дескрипторы для каналов наследуются порожденным процессом после

fork
, и если они не закрываются, все еще доступны после
exec
. Вскоре мы увидим, как использовать это обстоятельство и сделать с каналами что-то интересное.

9.3.1.2. Буферирование каналов

Каналы буферируют свои данные, что означает, что записанные в канал данные хранятся ядром до тех пор, пока не будут прочитаны. Однако, канал может содержать лишь такое-то количество записанных, но еще не прочитанных данных. Мы можем называть записывающий процесс производителем, а читающий процесс потребителем. Как система управляет полными и пустыми каналами?

Когда канал полон, система автоматически блокирует производителя в следующий раз, когда он пытается осуществить запись данных в канал с помощью

write
. Когда канал освобождается, система копирует данные в канал, а затем позволяет системному вызову
write
вернуться к производителю.

Подобным же образом, если канал пустой, потребитель блокируется в

read
до тех пор, пока в канале не появятся данные для чтения. (Блокирующее поведение можно отключить; это обсуждается в разделе 9.4.3.4 «Неблокирующий ввод/вывод для каналов и очередей FIFO».)

Когда производитель вызывает на записывающем конце канала

close
, потребитель может успешно прочесть любые данные, все еще находящиеся в канале. После этого дальнейшие вызовы
read
возвращают 0, указывая на конец файла.

Напротив, если потребитель закрывает читаемый конец,

write
на записываемом конце завершается неудачей. В частности, ядро посылает производителю сигнал «нарушенный канал», действием по умолчанию для которого является завершение процесса.

Поделиться:
Популярные книги

Черный Маг Императора 18

Герда Александр
18. Черный маг императора
Фантастика:
юмористическое фэнтези
аниме
сказочная фантастика
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Черный Маг Императора 18

Первый среди равных. Книга XII

Бор Жорж
12. Первый среди Равных
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Первый среди равных. Книга XII

Хозяин Стужи

Петров Максим Николаевич
1. Злой Лед
Фантастика:
аниме
фэнтези
попаданцы
7.00
рейтинг книги
Хозяин Стужи

Я уже граф. Книга VII

Дрейк Сириус
7. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я уже граф. Книга VII

Прах к праху

Джордж Элизабет
7. Инспектор Линли
Детективы:
классические детективы
8.17
рейтинг книги
Прах к праху

На границе империй. Том 10. Часть 6

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 6

Эволюционер из трущоб. Том 12

Панарин Антон
12. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Эволюционер из трущоб. Том 12

Кодекс Охотника. Книга XXXII

Винокуров Юрий
32. Кодекс Охотника
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXXII

Инженер Петра Великого 2

Гросов Виктор
2. Инженер Петра Великого
Фантастика:
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Инженер Петра Великого 2

Алые перья стрел

Крапивин Владислав Петрович
Детские:
детские приключения
8.58
рейтинг книги
Алые перья стрел

Внук сотника

Красницкий Евгений Сергеевич
1. Отрок
Приключения:
исторические приключения
9.01
рейтинг книги
Внук сотника

Я не князь. Книга XIII

Дрейк Сириус
13. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я не князь. Книга XIII

Обрыв

Гончаров Иван Александрович
Проза:
классическая проза
русская классическая проза
8.93
рейтинг книги
Обрыв

Ваше Сиятельство 8

Моури Эрли
8. Ваше Сиятельство
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Ваше Сиятельство 8