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

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

Жанры

Linux программирование в примерах
Шрифт:

9.3.1.1. Создание каналов

Системный вызов

pipe
создает канал:

#include <unistd.h> /* POSIX */

int pipe(int filedes[2]);

Значение аргумента является адресом массива из двух элементов целого типа,

pipe
возвращает 0 при успешном возвращении и -1, если была ошибка.

Если вызов был успешным, у процесса теперь есть два дополнительных открытых дескриптора файла. Значение

filedes[0]
является читаемым концом канала, a
filedes [1]
 — записываемым
концом
. (Удобным мнемоническим способом запоминания является то, что читаемый конец использует индекс 0, аналогичный дескриптору стандартного ввода 0, а записываемый конец использует индекс 1, аналогичный дескриптору стандартного вывода 1.)

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

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».)

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

Феномен Солженицына

Сарнов Бенедикт Михайлович
Документальная литература:
биографии и мемуары
6.25
рейтинг книги
Феномен Солженицына

Бандит

Щепетнов Евгений Владимирович
1. Петр Синельников
Фантастика:
фэнтези
7.92
рейтинг книги
Бандит

Стеллар. Компиляция. Книги 1-9

Прокофьев Роман Юрьевич
Стеллар
Фантастика:
киберпанк
рпг
постапокалипсис
технофэнтези
5.00
рейтинг книги
Стеллар. Компиляция. Книги 1-9

Черный Баламут. Трилогия

Олди Генри Лайон
Черный Баламут
Фантастика:
героическая фантастика
5.00
рейтинг книги
Черный Баламут. Трилогия

Уиронда. Другая темнота (сборник)

Музолино Луиджи
Фантастика:
ужасы и мистика
5.00
рейтинг книги
Уиронда. Другая темнота (сборник)

Париж в 1814-1848 годах. Повседневная жизнь

Мильчина Вера Аркадьевна
Культура повседневности
Научно-образовательная:
история
культурология
5.00
рейтинг книги
Париж в 1814-1848 годах. Повседневная жизнь

Жизнь и приключения Мартина Чезлвита

Диккенс Чарльз
Проза:
классическая проза
7.86
рейтинг книги
Жизнь и приключения Мартина Чезлвита

Легенды российских тамплиеров

Никитин Андрей Леонидович
Религия и эзотерика:
эзотерика
5.00
рейтинг книги
Легенды российских тамплиеров

Избранник Небес

Кадеш Алек
Фантастика:
ужасы и мистика
6.00
рейтинг книги
Избранник Небес

Юся и эльф

Демина Карина
Фантастика:
юмористическое фэнтези
детективная фантастика
6.25
рейтинг книги
Юся и эльф

Аргонавты

Дионис Антонио
Старинная литература:
мифы. легенды. эпос
5.00
рейтинг книги
Аргонавты

Боги и человек (статьи)

Синюков Борис Прокопьевич
Научно-образовательная:
культурология
5.00
рейтинг книги
Боги и человек (статьи)

Второгодка. Книга 3. Ученье свет

Ромов Дмитрий
3. Второгодка
Фантастика:
городское фэнтези
сказочная фантастика
альтернативная история
5.25
рейтинг книги
Второгодка. Книга 3. Ученье свет

День Победы. Гексалогия

Завадский Андрей Сергеевич
Фантастика:
боевая фантастика
5.00
рейтинг книги
День Победы. Гексалогия