Bidirektional. Gemeint für die Netzwerkkommunikation, kann aber auch lokal verwendet werden. Kann für verschiedene Protokolle verwendet werden. Es gibt keine Nachrichtengrenze für TCP. Rufen Sie an socket(2).
Ein Synchronisationsmechanismus für mehrere Prozesse oder Threads, ähnlich einer Warteschlange von Personen, die auf das Badezimmer warten. Siehe sys / sem.h .
Führen Sie Ihre eigene Parallelitätskontrolle durch. Rufen Sie an shmget(2).
Problem mit der Nachrichtengrenze
Ein entscheidender Faktor bei der Auswahl einer Methode gegenüber der anderen ist das Problem der Nachrichtengrenze. Sie können erwarten, dass "Nachrichten" voneinander diskret sind, dies gilt jedoch nicht für Byte-Streams wie TCP oder Pipe.
Betrachten Sie ein Paar Echo-Client und -Server. Der Client sendet eine Zeichenfolge, der Server empfängt sie und sendet sie sofort zurück. Angenommen, der Client sendet "Hallo", "Hallo" und "Wie wäre es mit einer Antwort?".
Mit Byte-Stream-Protokollen kann der Server "Hell", "oHelloHow" und "about a answer?" Empfangen. oder realistischer "Hallo Hallo, wie wäre es mit einer Antwort?". Der Server hat keine Ahnung, wo sich die Nachrichtengrenze befindet.
Ein uralter Trick besteht darin, die Nachrichtenlänge auf CHAR_MAXoder zu beschränken UINT_MAXund zuzustimmen, die Nachrichtenlänge zuerst in charoder zu senden uint. Wenn Sie also auf der Empfangsseite sind, müssen Sie zuerst die Nachrichtenlänge lesen. Dies bedeutet auch, dass jeweils nur ein Thread die Nachricht lesen sollte.
Mit diskreten Protokollen wie UDP oder Nachrichtenwarteschlangen müssen Sie sich nicht um dieses Problem kümmern, aber programmgesteuerte Byte-Streams sind einfacher zu handhaben, da sie sich wie Dateien und stdin / out verhalten.
Eine kleine nit: pipe (2) kann auch in Geschwisterprozessen verwendet werden - zum Beispiel ist die Shell allen Prozessen in der Pipeline übergeordnet.
Hudson
5
Beachten Sie, dass Sie nachrichtenorientierte Unix-Domain-Sockets haben können. Im Gegensatz zu Internet sind sie zuverlässig.
Tom Anderson
2
Gibt es einen Benchmark oder einen qualitativen Leistungsvergleich dieser Ansätze?
Kakyo
17
Shared Memory kann am effizientesten sein, da Sie darauf Ihr eigenes Kommunikationsschema aufbauen. Es erfordert jedoch viel Sorgfalt und Synchronisierung. Es sind Lösungen verfügbar, um gemeinsam genutzten Speicher auf andere Computer zu verteilen.
Steckdosen sind heutzutage am tragbarsten, erfordern jedoch mehr Overhead als Rohre. Die Möglichkeit, Sockets lokal oder über ein Netzwerk transparent zu verwenden, ist ein großer Bonus.
Nachrichtenwarteschlangen und -signale eignen sich hervorragend für harte Echtzeitanwendungen, sind jedoch nicht so flexibel.
Diese Methoden wurden natürlich für die Kommunikation zwischen Prozessen entwickelt, und die Verwendung mehrerer Threads innerhalb eines Prozesses kann die Dinge komplizieren - insbesondere bei Signalen.
DBUS verwendet einen oder mehrere dieser Mechanismen. Es gibt einige langjährige Arbeiten an ihrem eigenen IPC-Mechanismus namens DBUS1 (oder KDBUS ...), der jedoch noch nicht in den Mainline-Kernel integriert wurde.
Phillip Whelan
8
Es ist erwähnenswert, dass viele Bibliotheken eine Art von Dingen übereinander implementieren.
Der gemeinsam genutzte Speicher muss nicht die schrecklichen Funktionen des gemeinsam genutzten sysv-Speichers verwenden - es ist viel eleganter, mmap () zu verwenden (mmap eine Datei in einem tmpfs / dev / shm, wenn Sie den Namen haben möchten; mmap / dev / zero, wenn Sie möchten gabelte nicht ausgeführte Prozesse, um sie anonym zu erben). Trotzdem müssen Ihre Prozesse immer noch synchronisiert werden, um Probleme zu vermeiden. In der Regel werden einige der anderen IPC-Mechanismen verwendet, um den Zugriff auf einen gemeinsam genutzten Speicherbereich zu synchronisieren.
Ich hatte noch nie von mmaping / dev / zero gehört. Genial! Sie erwähnen, dass es nur für untergeordnete Elemente freigegeben werden kann. Können Sie den von Ihnen verwendeten Dateideskriptor mithilfe von cmsg / SCM_RIGHTS über einen Unix-Domain-Socket an einen nicht verwandten Prozess senden und dort eine gemeinsame Zuordnung erhalten? Oder ist es das Mapping, das Sie erben, nicht der Dateideskriptor? Selbst wenn es funktioniert, benötigen Sie den Socket noch irgendwo im Dateisystem, um dies zu tun. Selbst wenn die Zuordnung anonym ist, ist der Socket, der zum Einrichten verwendet wird, dies nicht. Guh. IPC ist schwer. Gehen wir einkaufen!
Tom Anderson
mmaping / dev / zero wird tatsächlich von einigen Arten der Speicherzuweisung verwendet. Der Vorteil ist jedoch, dass MAP_SHARED bei Verwendung mit Ihren untergeordneten Prozessen von fork () gemeinsam genutzt wird (normalerweise wird der Speicher logisch kopiert). Können Sie es mit einem nicht verwandten Prozess teilen? Das glaube ich nicht. Ich vermute, dass der Aufruf von mmap () freigegeben werden muss, nicht der Dateideskriptor.
Antworten:
Unix IPC
Hier sind die großen Sieben:
Rohr
Nützlich nur bei Prozessen, die als Eltern / Kind zusammenhängen. Rufen Sie an
pipe(2)
undfork(2)
. Unidirektional.FIFO oder Named Pipe
Zwei nicht verwandte Prozesse können FIFO im Gegensatz zu Plain Pipe verwenden. Rufen Sie an
mkfifo(3)
. Unidirektional.Socket und Unix Domain Socket
Bidirektional. Gemeint für die Netzwerkkommunikation, kann aber auch lokal verwendet werden. Kann für verschiedene Protokolle verwendet werden. Es gibt keine Nachrichtengrenze für TCP. Rufen Sie an
socket(2)
.Nachrichtenwarteschlange
Das Betriebssystem verwaltet eine diskrete Nachricht. Siehe sys / msg.h .
Signal
Das Signal sendet eine Ganzzahl an einen anderen Prozess. Passt nicht gut zu Multithreads. Rufen Sie an
kill(2)
.Semaphor
Ein Synchronisationsmechanismus für mehrere Prozesse oder Threads, ähnlich einer Warteschlange von Personen, die auf das Badezimmer warten. Siehe sys / sem.h .
Geteilte Erinnerung
Führen Sie Ihre eigene Parallelitätskontrolle durch. Rufen Sie an
shmget(2)
.Problem mit der Nachrichtengrenze
Ein entscheidender Faktor bei der Auswahl einer Methode gegenüber der anderen ist das Problem der Nachrichtengrenze. Sie können erwarten, dass "Nachrichten" voneinander diskret sind, dies gilt jedoch nicht für Byte-Streams wie TCP oder Pipe.
Betrachten Sie ein Paar Echo-Client und -Server. Der Client sendet eine Zeichenfolge, der Server empfängt sie und sendet sie sofort zurück. Angenommen, der Client sendet "Hallo", "Hallo" und "Wie wäre es mit einer Antwort?".
Mit Byte-Stream-Protokollen kann der Server "Hell", "oHelloHow" und "about a answer?" Empfangen. oder realistischer "Hallo Hallo, wie wäre es mit einer Antwort?". Der Server hat keine Ahnung, wo sich die Nachrichtengrenze befindet.
Ein uralter Trick besteht darin, die Nachrichtenlänge auf
CHAR_MAX
oder zu beschränkenUINT_MAX
und zuzustimmen, die Nachrichtenlänge zuerst inchar
oder zu sendenuint
. Wenn Sie also auf der Empfangsseite sind, müssen Sie zuerst die Nachrichtenlänge lesen. Dies bedeutet auch, dass jeweils nur ein Thread die Nachricht lesen sollte.Mit diskreten Protokollen wie UDP oder Nachrichtenwarteschlangen müssen Sie sich nicht um dieses Problem kümmern, aber programmgesteuerte Byte-Streams sind einfacher zu handhaben, da sie sich wie Dateien und stdin / out verhalten.
quelle
Shared Memory kann am effizientesten sein, da Sie darauf Ihr eigenes Kommunikationsschema aufbauen. Es erfordert jedoch viel Sorgfalt und Synchronisierung. Es sind Lösungen verfügbar, um gemeinsam genutzten Speicher auf andere Computer zu verteilen.
Steckdosen sind heutzutage am tragbarsten, erfordern jedoch mehr Overhead als Rohre. Die Möglichkeit, Sockets lokal oder über ein Netzwerk transparent zu verwenden, ist ein großer Bonus.
Nachrichtenwarteschlangen und -signale eignen sich hervorragend für harte Echtzeitanwendungen, sind jedoch nicht so flexibel.
Diese Methoden wurden natürlich für die Kommunikation zwischen Prozessen entwickelt, und die Verwendung mehrerer Threads innerhalb eines Prozesses kann die Dinge komplizieren - insbesondere bei Signalen.
quelle
Hier ist eine Webseite mit einem einfachen Benchmark: https://sites.google.com/site/rikkus/sysv-ipc-vs-unix-pipes-vs-unix-sockets
Soweit ich das beurteilen kann, hat jeder seine Vorteile:
quelle
Es ist erwähnenswert, dass viele Bibliotheken eine Art von Dingen übereinander implementieren.
Der gemeinsam genutzte Speicher muss nicht die schrecklichen Funktionen des gemeinsam genutzten sysv-Speichers verwenden - es ist viel eleganter, mmap () zu verwenden (mmap eine Datei in einem tmpfs / dev / shm, wenn Sie den Namen haben möchten; mmap / dev / zero, wenn Sie möchten gabelte nicht ausgeführte Prozesse, um sie anonym zu erben). Trotzdem müssen Ihre Prozesse immer noch synchronisiert werden, um Probleme zu vermeiden. In der Regel werden einige der anderen IPC-Mechanismen verwendet, um den Zugriff auf einen gemeinsam genutzten Speicherbereich zu synchronisieren.
quelle