Auf dieser Seite aus Das Design und die Implementierung des 4.4BSD-Betriebssystems heißt es:
Ein Hauptunterschied zwischen Pipes und Sockets besteht darin, dass Pipes einen gemeinsamen übergeordneten Prozess zum Einrichten des Kommunikationskanals benötigen
Wenn ich jedoch richtig aufzeichne, ist die einzige Möglichkeit, einen neuen Prozess zu erstellen, fork
ein vorhandener. Ich kann also nicht wirklich sehen, wie zwei Prozesse keinen gemeinsamen Vorfahren haben könnten. Habe ich dann Recht zu glauben, dass jedes Prozesspaar miteinander verbunden werden kann?
ps auxf
eine Idee zu Prozessvorfahren an.Antworten:
Nicht wirklich.
Die Rohre müssen vom übergeordneten Prozess eingerichtet werden, bevor das Kind oder die Kinder gegabelt werden. Sobald der untergeordnete Prozess gegabelt ist, können seine Dateideskriptoren nicht mehr "von außen" manipuliert werden (wobei Dinge wie Debugger ignoriert werden). Der übergeordnete Prozess (oder ein anderer Prozess) kann den Teil "Einrichten des Kommunikationskanals" nicht nachträglich ausführen .
Wenn Sie also zwei zufällige Prozesse verwenden, die bereits ausgeführt werden, können Sie keine Pipe direkt zwischen ihnen einrichten. Sie müssen eine Art Socket (oder einen anderen IPC-Mechanismus) verwenden, um die Kommunikation zu ermöglichen. (Beachten Sie jedoch, dass einige Betriebssysteme, darunter auch FreeBSD, das Senden von Dateideskriptoren auf Unix-Domain-Sockets ermöglichen.)
quelle
Dieser Satz ist nicht sehr klar. Erstens Elternteil sollte Vorfahre , da der Prozess das Rohr der Einrichtung kann ein Elternteil oder ein Großelternteil , oder ein Grand-Enkel ... -grandparent, oder eine der kommunizierenden Prozesse. Zweitens bedeutet der Satz nicht "Wenn Sie eine Pipe wollen, muss es einen gemeinsamen Ahnenprozess geben", sondern "Wenn Sie eine Pipe wollen, muss ein gemeinsamer Ahnenprozess sie einrichten".
Unter der Haube baut ein Prozess ein Rohr mit sich selbst auf. Die Pipe ist ein Dateideskriptor wie jeder andere, genauer gesagt ein Paar von Dateideskriptoren, einer für jedes Ende. Der Prozess, der die Pipe erstellt hat, kann sie sofort verwenden, um Daten an sich selbst zu senden, obwohl dies selten nützlich ist (obwohl eine Self-Pipe ihre Verwendung hat).
Eine typische Redewendung besteht darin, dass ein Prozess eine Pipe einrichtet, dann einen untergeordneten Prozess aufteilt und ein Ende der Pipe im übergeordneten und das andere Ende der Pipe im untergeordneten Prozess schließt. Auf diese Weise können der übergeordnete und der untergeordnete Prozess in eine Richtung kommunizieren. Wenn die Prozesse eine bidirektionale Kommunikation benötigen, benötigen sie zwei Pipes (außer bei einigen Unix-Varianten, bei denen Pipes bidirektional sind).
Die Pipes werden wiederum von untergeordneten Elementen geerbt, sodass der Prozess, der die Pipe erstellt hat, möglicherweise nicht an der Kommunikation beteiligt ist. Eine Pipe in einer Shell, die zwischen zwei externen Befehlen erstellt wurde,
ls | rot13
umfasst beispielsweise die folgenden Schritte:execve
aufls
.execve
aufrot13
.Wenn zwei vorhandene Prozesse miteinander kommunizieren möchten, können sie eine Named Pipe verwenden . (Nun, es wird auch ein Dateideskriptor übergeben , aber es ist nichts für schwache Nerven.)
quelle
Die Shell der Pipeline ist das gemeinsame übergeordnete Element, das einen Kommunikationskanal zwischen den verschiedenen Mitgliedern der Pipeline einrichtet.
Jeder Prozess kann an jeden anderen weitergeleitet werden. Die einzigen Prozesse, die sinnvollerweise miteinander verbunden werden können , sind "Filter", die von stdin lesen und in stdout schreiben.
Zum Beispiel, wenn Sie den Befehl ausgeben
ps -eaH
wird zeigen, dass die Katze und ihre zwei Schwänze Kinder der aufrufenden Schale sind:quelle