Вход/Регистрация
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. Буферирование каналов

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

  • Читать дальше
  • 1
  • ...
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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