Linux программирование в примерах - Роббинс Арнольд
Строки 72–83 делают подобные же шаги для правого потомка. Вот что происходит при запуске:
$ <b>ch09-pipeline</b> /* Запуск программы */left child terminated, status: 0 /* Левый потомок завершается до вывода (!) */hello there /* Вывод от правого потомка */right child terminated, status: 0$ <b>ch09-pipeline</b> /* Повторный запуск программы */hello there /* Вывод от правого потомка и ... */right child terminated, status: 0 /* Правый потомок завершается до левого */left child terminated, status: 0Обратите внимание, что порядок, в котором завершаются потомки, не является детерминированным. Он зависит от загрузки системы и многих других факторов, которые могут повлиять на планирование процессов. Вам следует проявить осторожность, чтобы избежать предположений о порядке действий при написании кода, создающего несколько процессов, в особенности для кода, который вызывает семейство функций
wait()Весь процесс показан на рис. 9.5.



Рис. 9.5. Создание конвейера родителем
На рис. 9.5 (а) изображена ситуация после создания родителем канала (строки 22–25) и двух порожденных процессов (строки 27–37).
На рис. 9.5 (b) показана ситуация после закрытия родителем канала (строки 39–40) и начала ожидания порожденных процессов (строки 42–50). Каждый порожденный процесс поместил канал на место стандартного вывода (левый потомок, строки 61–63) и стандартного ввода (строки 76–78).
Наконец, рис. 9.5 (с) изображает ситуацию после закрытия потомками первоначального канала (строки 64 и 79) и вызова
execvp()9.4.2. Создание нелинейных конвейеров:
/dev/fd/XXМногие современные системы Unix, включая GNU/Linux, поддерживают в каталоге
/dev/fd/dev/fd/0/dev/fd/1open()dup()Эти специальные файлы находят свое применение на уровне оболочки: Bash,
ksh88ksh93<(...)>(...)diffcommand1 > /tmp/out.$$.1command2 > /tmp/out.$$.2diff /tmp/out.$$.1 /tmp/out.$$.2rm /tmp/out.$$.1 /tmp/out.$$.2С замещением процессов это выглядит следующим образом:
diff <(command1) <(command2)Не надо никаких беспорядочных файлов для временного запоминания и удаления. Например, следующая команда показывает, что наш домашний каталог является ссылкой на другой каталог:
$ <b>diff <(pwd) <(/bin/pwd)</b>1c1< /home/arnold/work/prenhall/progex---> /d/home/arnold/work/prenhall/progexНезамысловатая команда
pwdcd/bin/pwdКак выглядит замещение процессов? Оболочка создает вспомогательные команды [99] ('
pwd/bin/pwddiff<i>/dev/fd</i>$ <b>set -х</b> /* Включить трассировку исполнения */$ <b>diff <(pwd) <(/bin/pwd)</b> /* Запустить команду */+ diff /dev/fd/63 /dev/fd/62 /* Трассировка оболочки: главная, программа, обратите внимание на аргументы */++ pwd /* Трассировка оболочки: вспомогательные программы */++ /bin/pwd1c1 /* Вывод diff */< /home/arnold/work/prenhall/progex---> /d/home/arnold/work/prenhall/progexЭто показано на рис. 9.6.

Рис. 9.6. Замещение процесса
Если на вашей системе есть
/dev/fd9.4.3. Управление атрибутами файла:
fcntl()Системный вызов
fcntl()#include <unistd.h> /* POSIX */#include <fcntl.h>int fcntl (int fd, int cmd);int fcntl(int fd, int cmd, long arg);