it-swarm.com.de

Schnellste Technik zum Weiterleiten von Nachrichten zwischen Prozessen unter Linux?

Was ist die schnellste Technologie zum Senden von Nachrichten zwischen C++ - Anwendungsprozessen unter Linux? Mir ist vage bewusst, dass folgende Techniken auf dem Tisch liegen:

  • TCP
  • UDP
  • Steckdosen
  • Pfeifen
  • Named Pipes
  • Gedächtnis zugeordnete Dateien

gibt es noch mehr möglichkeiten und was ist der schnellste? 

29
user997112

Ich würde vorschlagen, sich das auch anzuschauen: Verwendung von Shared Memory unter Linux in C .

Grundsätzlich würde ich Netzwerkprotokolle wie TCP und UDP ablegen, wenn IPC auf einem einzelnen Computer ausgeführt wird. Diese haben einen Paketierungsaufwand und sind an noch mehr Ressourcen gebunden (z. B. Ports, Loopback-Schnittstelle).

13
Sam

Alle diese Antworten sind zwar sehr gut, aber ich denke, wir müssten darüber diskutieren, was "am schnellsten" ist (und muss es "am schnellsten" oder nur "schnell genug" sein?).

Für große Nachrichten besteht kein Zweifel, dass Shared Memory eine sehr gute Technik ist und in vielerlei Hinsicht sehr nützlich ist. 

Wenn die Nachrichten jedoch klein sind, gibt es Nachteile, wenn Sie Ihr eigenes Nachrichtenübermittlungsprotokoll und eine Methode zum Informieren des anderen Prozesses über das Vorhandensein einer Nachricht aufstellen müssen. 

Pipes und Named Pipes sind in diesem Fall viel einfacher zu verwenden - sie verhalten sich ziemlich wie eine Datei, Sie schreiben nur Daten auf der sendenden Seite und lesen die Daten auf der empfangenden Seite. Wenn der Sender etwas schreibt, wird die Empfängerseite automatisch aktiviert. Wenn die Leitung voll ist, wird die sendende Seite blockiert. Wenn keine Daten mehr vom Absender vorhanden sind, wird die Empfangsseite automatisch gesperrt. Dies bedeutet, dass dies in relativ wenigen Codezeilen implementiert werden kann, mit einer ziemlich guten Garantie, dass es jederzeit und jederzeit funktioniert. 

Auf der anderen Seite verwendet Shared Memory einen anderen Mechanismus, um den anderen Thread darüber zu informieren, dass "Sie ein Datenpaket zur Verarbeitung haben". Ja, es ist sehr schnell, wenn Sie große Datenpakete kopieren möchten - aber ich wäre überrascht, wenn es wirklich einen großen Unterschied zu einer Pipe gibt. Der Hauptvorteil wäre, dass die andere Seite die Daten nicht aus dem gemeinsam genutzten Speicher kopieren muss, sondern auch, dass genügend Speicherplatz vorhanden ist, um alle Meldungen "im Flug" zu speichern, oder der Sender, der die Möglichkeit hat, Dinge zurückzuhalten . 

Ich sage nicht "kein gemeinsames Gedächtnis verwenden", ich sage nur, dass es keine "Lösung gibt, die alle Probleme" am besten "löst. 

Um dies zu klären: Ich würde zunächst eine einfache Methode implementieren, die eine Pipe oder eine Named Pipe verwendet (je nachdem, was für die Zwecke geeignet ist) und die Leistung davon messen. Wenn das Kopieren der Daten viel Zeit in Anspruch nimmt, würde ich andere Methoden in Betracht ziehen. 

Eine andere Überlegung sollte natürlich darin bestehen, "wir werden immer zwei separate Maschinen [oder zwei virtuelle Maschinen auf demselben System] verwenden, um dieses Problem zu lösen. In diesem Fall ist eine Netzwerklösung die bessere Wahl - selbst wenn sie nicht die schnellste ist Ich habe einen lokalen TCP - Stack auf meinen Rechnern zu Benchmark-Zwecken eingesetzt und habe bei anhaltendem Datenverkehr etwa 20 bis 30 Gbit/s (2-3 GB/s) erhalten -100 GBit/s (5-10GB/s) (es sei denn, die Blockgröße ist WIRKLICH winzig und passt in den L1-Cache.) Ich habe keine Standardpipe gemessen, aber ich gehe davon aus, dass sich diese beiden Zahlen in der Mitte befinden. [Dies sind Zahlen, die für eine Reihe verschiedener mittelgroßer, recht moderner PCs recht gut geeignet sind - natürlich erwarten Sie bei einem ARM-, MIPS- oder anderen Embedded-Controller eine niedrigere Anzahl für alle diese Methoden.]

37
Mats Petersson

Die NetOS Systems Research Group von der Cambridge University, Großbritannien, hat einige (Open Source) IPC Benchmarks durchgeführt. 

Der Quellcode befindet sich unter https://github.com/avsm/ipc-bench

Projektseite: http://www.cl.cam.ac.uk/research/srg/netos/projects/ipc-bench/ .

Ergebnisse: http://www.cl.cam.ac.uk/research/srg/netos/projects/ipc-bench/results.html

Diese Forschung wurde mit den obigen Ergebnissen veröffentlicht: http://anil.recoil.org/papers/drafts/2012-usenix-ipc-draft1.pdf

7
DejanLekic

Überprüfen Sie CMA und kdbus: https://lwn.net/Articles/466304/

Ich denke, das schnellste Zeug in diesen Tagen basiert auf AIO . http://www.kegel.com/c10k.html

3
Alex

Da Sie diese Frage mit C++ markiert haben, empfehle ich Boost.Interprocess :

Shared Memory ist der schnellste Interprozess-Kommunikationsmechanismus. Das Betriebssystem bildet ein Speichersegment im Adressraum mehrerer Prozesse, so dass mehrere Prozesse in diesem Speicher lesen und schreiben können Segment ohne Aufruf von Betriebssystemfunktionen. Wir brauchen jedoch eine Art Synchronisation zwischen Prozessen, die lesen und schreiben geteilte Erinnerung.

Quelle

Ein Nachteil, den ich gefunden habe, sind die Einschränkungen der Portabilität für Synchronisationsprimitive . Weder OS X noch Windows verfügen über eine native Implementierung für Interprozess-Zustandsvariablen, z. B. Sie emuliert sie daher mit Spin-Locks.

Wenn Sie nun ein * nix verwenden, das gemeinsam genutzte POSIX-Grundelemente unterstützt, treten keine Probleme auf.

Shared Memory mit Synchronisation ist ein guter Ansatz, wenn erhebliche Daten betroffen sind.

2
pepper_chico

Nun, Sie könnten einfach ein Shared Memory-Segment zwischen Ihren Prozessen haben, indem Sie den gemeinsamen Linux-Speicher aka SHM verwenden.

Es ist sehr einfach zu bedienen, siehe den Link für einige Beispiele.

1
cmc

posix Message Queues sind ziemlich schnell, haben aber einige Einschränkungen

0
arash kordi