До сих пор вы могли передавать данные только между связанными программами, т.е. программами, которые стартовали из общего процесса-предка. Часто это очень неудобно, хотелось бы, чтобы и у несвязанных процессов была возможность обмениваться данными.
Вы можете сделать это с помощью каналов FIFO, часто называемых
Вы можете создавать именованные каналы из командной строки и внутри программы. С давних времен программой создания их в командной строке была команда mknod
$ mknod
Однако команды mknod
$ mkfifo
У некоторых более старых версий UNIX была только команда mknod
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.
Далее приведен исходный текст примера 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 и тоже обозначает канал.Как это работает
Программа применяет функцию mkfifo
0777, он заменяется пользовательской маской (umask), устанавливаемой (в данном случае 022) точно так же, как при создании обычного файла, поэтому у результирующего файла режим 755. Если ваша umask установлена иначе, например, ее значение 0002, вы увидите другие права доступа у созданного файла.Удалить FIFO можно как традиционный файл с помощью команды rm
unlink.Доступ к FIFO
У именованных каналов есть одно очень полезное свойство: поскольку они появляются в файловой системе, их можно применять в командах на месте обычного имени файла. Прежде чем вы продолжите программирование с использованием созданного вами файла FIFO, давайте исследуем поведение такого файла с помощью обычных команд для работы с файлом (упражнение 13.10).
1. Сначала попробуйте прочесть (пустой) файл FIFO:
$ cat < /tmp/my_fifo
2. Теперь попытайтесь записать в FIFO. Вам придется использовать другой терминал, поскольку первая команда в данный момент "зависла" в ожидании появления каких-нибудь данных в FIFO:
$ echo "Hello World" > /tmp/my_fifo
Вы увидите вывод команды cat
cat будет ждать до тех пор, пока вы не прервете ее выполнение, традиционно комбинацией клавиш 3. Можно выполнить обе команды одновременно, переведя первую в фоновый режим:
$ cat < /tmp/my_fifo &
[1] 1316
$ echo "Hello World" > /tmp/my_fifo
Hello World
[1]+ Done cat
$
Как это работает
Поскольку в канале FIFO не было данных, обе команды, cat
echo, приостанавливают выполнение, ожидая, соответственно, поступления каких-нибудь данных и какого-либо процесса для их чтения.