На этой странице из Проекта и внедрения операционной системы 4.4BSD сказано, что:
Основное различие между каналами и сокетами заключается в том, что каналам требуется общий родительский процесс для настройки канала связи.
Однако, если я записываю правильно, единственный способ создать новый процесс - fork
это существующий. Поэтому я не могу понять, как 2 процесса не могут иметь общего предка. Правильно ли тогда считать, что любая пара процессов может передаваться друг другу?
ps auxf
идею о предках процесса.Ответы:
На самом деле, нет.
Каналы должны быть установлены родительским процессом до того, как дочерний или дочерний процесс будет разветвлен. После того, как дочерний процесс разветвлен, его файловые дескрипторы не могут манипулировать «извне» (игнорируя такие вещи, как отладчики), родительский (или любой другой процесс) не может выполнить «настройку канала связи» после факта. ,
Поэтому, если вы возьмете два случайных процесса, которые уже запущены, вы не сможете установить канал между ними напрямую. Вам нужно использовать какую-либо форму сокета (или другой механизм IPC), чтобы заставить их общаться. (Но учтите, что некоторые операционные системы, в том числе FreeBSD, позволяют отправлять файловые дескрипторы на сокеты домена Unix.)
источник
Это предложение не очень понятно. Во-первых, родитель должен быть предком , поскольку процесс, устанавливающий канал, может быть родителем, или прародителем, или пра-пра-пра-прародителем, или одним из взаимодействующих процессов. Во-вторых, предложение не означает «если вы хотите конвейер, должен существовать общий процесс предка», но «если вы хотите конвейер, процесс общего предка должен его настроить».
Под капотом процесс устанавливает трубу с собой. Канал - это файловый дескриптор, как и любой другой, а точнее пара файловых дескрипторов, по одному для каждого конца. Процесс, создавший канал, может немедленно использовать его для отправки данных самому себе, хотя это редко бывает полезно (хотя самотрубка действительно имеет свое применение).
Типичная идиома для процесса - установить канал, затем разветвить дочерний процесс и закрыть один конец канала в родительском, а другой конец канала в дочернем. Это позволяет родительскому и дочернему процессам общаться в одном направлении. Если процессам требуется двунаправленная связь, им нужны два канала (за исключением некоторых вариантов Unix, где каналы являются двунаправленными).
Каналы по очереди наследуются любыми дочерними элементами, поэтому процесс, который создал канал, может не участвовать в обмене данными. Например, канал в оболочке, созданный между двумя внешними командами, такими как,
ls | rot13
включает следующие шаги:execve
наls
.execve
наrot13
.Если два существующих процесса хотят общаться друг с другом, они могут использовать именованный канал . (Ну, есть также передача файлового дескриптора , но это не для слабонервных.)
источник
Оболочка конвейера является общим родителем, который устанавливает канал связи между несколькими членами конвейера.
Любой процесс может быть передан любому другому. Единственные процессы, которые можно с пользой объединить, это «фильтры», которые читают из stdin и записывают в stdout.
Например, если вы выполните команду
ps -eaH
покажет, что кошка и два ее хвоста являются потомками вызывающей оболочки:источник