Далее дочерний процесс может применить exec
для вызова любой программы, которая читает стандартный ввод. В данном случае мы используем команду od
. Команда od
будет ждать, когда данные станут ей доступны, как если бы она ждала ввода с терминала пользователя. В действительности без специального программного кода, позволяющего непосредственно выяснить разницу, она не будет знать, что ввод приходит из канала, а не с терминала.
Родительский процесс начинает с закрытия конца чтения канала, file_pipes[0]
, потому что он никогда не будет читать из канала. Затем он пишет данные в канал. Когда все данные записаны, родительский процесс закрывает конец записи в канал и завершается. Поскольку теперь нет файловых дескрипторов, открытых для записи в канал, программа od
сможет считать три байта, записанных в канал, но последующие операции чтения далее будут возвращать 0 байтов, указывая на конец файла. Когда read
вернет 0, программа od
завершится. Это аналогично выполнению команды od
, введенной с терминала, и последующему нажатию комбинации клавиш + для отправки признака конца файла команде od
.
На рис. 13.3 показан результат вызова pipe
, на рис. 13.4 — результат вызова fork
, а на рис. 13.5 представлена программа, когда она готова к передаче данных.
Рис. 13.3
Рис. 13.4
Рис. 13.5
До сих пор вы могли передавать данные только между связанными программами, т.е. программами, которые стартовали из общего процесса-предка. Часто это очень неудобно, хотелось бы, чтобы и у несвязанных процессов была возможность обмениваться данными.
Вы можете сделать это с помощью каналов FIFO, часто называемых именованными каналами. Именованный канал — это файл специального типа (помните, что в ОС Linux все, что угодно, — файл!), существующий в виде имени в файловой системе, но ведущий себя как неименованные каналы, которые вы уже встречали.
Вы можете создавать именованные каналы из командной строки и внутри программы. С давних времен программой создания их в командной строке была команда mknod
:
$ mknod имя_файла p
Однако команды mknod
нет в списке команд X/Open, поэтому она включена не во все UNIX-подобные системы. Предпочтительнее применять в командной строке
$ mkfifo имя_файла
Примечание
У некоторых более старых версий UNIX была только команда mknod
. В стандарте X/Open issue 4 Version 2 есть вызов функции mknod
, но не программа командной строки. ОС Linux, как всегда настроенная дружелюбно, предлагает оба варианта: mknod
и mkfifo
.
Внутри программы можете применять два разных вызова:
#include
#include
int mkfifo(const char *filename, mode_t mode);
int mknod(const char* filename, mode_t mode | S_IFIFO, (dev_t)0);
Помимо команды mknod
вы можете использовать функцию mknod
для создания файлов специальных типов. Единственный переносимый вариант применения этой функции, создающий именованный канал, — использование значения 0 типа dev_t
и объединений с помощью операции or режима доступа к файлу и S_IFIFO
. В примерах мы будем применять более простую функцию mkfifo
.
Итак, выполните упражнение 13.9.
Упражнение 13.9. Создание именованного канала
Далее приведен исходный текст примера fifo1.c.
#include
#include
#include
#include
#include
int main() {
int res = mkfifo("/tmp/my_fifo", 0777);
if (res == 0) printf ("FIFO created\n");
exit(EXIT_SUCCESS);
}
Вы можете создать канал и заглянуть в него:
$ ./fifo1
FIFO created
$ ls -lF /tmp/my_fifo
prwxr-xr-x 1 rick users 0 2007-06-16 17:18 /tmp/my_fifo|
Обратите внимание на то, что первый символ вывода — р
, обозначающий канал. Символ |
в конце добавлен опцией -F
команды ls
и тоже обозначает канал.
Читать дальше