Ich habe gehört, dass FIFOs Pipes heißen. Und sie haben genau die gleiche Semantik. Auf der anderen Seite denke ich, dass Unix Domain Socket Pipe ziemlich ähnlich ist (obwohl ich es nie benutzt habe). Ich frage mich also, ob sich alle auf dieselbe Implementierung im Linux-Kernel beziehen. Irgendeine Idee?
30
Antworten:
UNIX-Domain-Sockets und FIFO können einen Teil ihrer Implementierung gemeinsam nutzen, sind jedoch konzeptionell sehr unterschiedlich. FIFO arbeitet auf sehr niedrigem Niveau. Ein Prozess schreibt Bytes in die Pipe und ein anderer liest daraus. Ein UNIX-Domain-Socket hat dasselbe Verhalten wie ein TCP / IP-Socket.
Ein Socket ist bidirektional und kann von vielen Prozessen gleichzeitig verwendet werden. Ein Prozess kann viele Verbindungen auf demselben Socket akzeptieren und mehrere Clients gleichzeitig bedienen. Der Kernel liefert jedes Mal einen neuen Dateideskriptor
connect(2)
oderaccept(2)
wird auf dem Socket aufgerufen. Die Pakete gehen immer zum richtigen Prozess.Bei einem FIFO wäre dies unmöglich. Für die bidirektionale Kommunikation benötigen Sie zwei FIFOs und für jeden Ihrer Clients ein FIFO-Paar. Es gibt keine Möglichkeit, selektiv zu schreiben oder zu lesen, da sie eine viel primitivere Art der Kommunikation darstellen.
Anonyme Pipes und FIFOs sind sehr ähnlich. Der Unterschied besteht darin, dass anonyme Pipes nicht als Dateien im Dateisystem vorhanden sind und daher von keinem Prozess verarbeitet werden können
open(2)
. Sie werden von Prozessen verwendet, die sie mit einer anderen Methode gemeinsam nutzen. Wenn ein Prozess ein FIFO öffnet und dann beispielsweise ein ausführt,fork(2)
erbt sein untergeordnetes Element seine Dateideskriptoren und unter anderem die Pipe.Die UNIX-Domänensockets, anonymen Pipes und FIFOs sind ähnlich, da sie gemeinsam genutzte Speichersegmente verwenden. Die Details der Implementierung können von einem System zum anderen variieren, aber die Idee ist immer die gleiche:
Fügen Sie denselben Teil des Speichers in zwei unterschiedliche Prozesse ein, um die gemeinsame Nutzung von Daten zu ermöglichen( Bearbeiten: Dies wäre eine naheliegende Möglichkeit, dies zu implementieren, aber das ist nicht, wie es tatsächlich in Linux gemacht wird, das einfach den Kernel-Speicher für die Puffer verwendet (siehe Antwort von @ tjb63 unten).
Der Kernel verarbeitet dann die Systemaufrufe und abstrahiert den Mechanismus.
quelle
Hier gibt es eine gute Diskussion darüber: http://www.slideshare.net/divyekapoor/linux-kernel-implementation-of-pipes-and-fifos
Soweit ich sehen kann, sind sowohl die Präsentationsfolien als auch die Quelle @ http://lxr.free-electrons.com/source/fs/pipe.c - fifos als Wrapper um Pipes implementiert, und die Pipes selbst sind implementiert über das virtuelle Dateisystem pipefs.
@lgeorget - Die Pipes scheinen den Kernel-Speicher für Puffer zwischen den Readern und den Writern zu verwenden. Sie verwenden nicht den 'Shared Memory' als solchen und kopieren den Speicher zwischen Benutzer- und Kernel-Adressräumen (z. B.
pipe_read
Aufrufepipe_iov_copy_to_user
, die aufrufen__copy_to_user_inatomic
(odercopy_to_user
)). .__copy_to_user_inatomic
Anrufecopy_user_generic
, die auf mehrere ASM - Implementierungen sind.quelle
Ein "FIFO" und eine " Named Pipe" sind dasselbe - obwohl sie sich stark davon unterscheiden, wie eine Shell eine "Pipe" (|) zwischen zwei Befehlen in der Befehlszeile behandelt.
Eine Named Pipe (FIFO) ist eine einzelne "Datei", die von zwei Programmen gemeinsam genutzt wird, wobei einer darauf schreibt und der andere daraus liest ... Ein Socket ist andererseits eine "Verbindung" zwischen zwei "Dateien" - was auch sein kann Verwenden Sie ein Netzwerk und arbeiten Sie auf getrennten Computern - wobei ein Programm in eine "Datei" liest / schreibt und ein anderes Programm in eine andere "Datei" liest / schreibt ... Ich glaube nicht, dass sie sich so ähnlich sind ... Auf der anderen Seite beides Sockets und Named Pipes sowie Dateien, Geräte und symbolische Verknüpfungen verwenden alle Inodes und implementieren einige gemeinsame Funktionen (wie Lesen und Schreiben).
quelle
Ich glaube nicht, Justin. Wenn ich mich nicht irre, und ich bin es sehr wahrscheinlich, denke ich, dass FIFOs eine Datei auf der Festplatte verwenden und Unix-Domain-Sockets den Kernel-Speicher verwenden.
Als Ergänzung zu dem obigen Poster, in dem erwähnt wurde, dass Unix-Domain-Sockets bidirektional sind, ist dies nur bei Verwendung eines SOCK_STREAM-Sockets der Fall. SOCK_DGRAM Unix-Domain-Sockets sind tatsächlich unidirektional und können nur vom Code connect () zum Code bind () senden ().
Natürlich muss der Code, der connect () aufgerufen hat, bind () aufrufen, um einen eigenen Endpunkt zu erstellen, aber das hat nichts mit Ihrer Frage zu tun.
quelle
Meine 2 Cent ... FIFO und UNIX-Socket sind beide bidirektional (ähnlich), aber Socket haben eine Sterntopologie, während ein FIFO nur eine Warteschlange ist (und sich daher nicht gegenseitig ersetzen kann).
**
quelle