2009-06-08 21 views
50

Ich habe kürzlich mit Nachrichtenwarteschlangen (System V, aber POSIX sollte auch in Ordnung sein) in Linux gespielt und sie scheinen perfekt für meine Anwendung, aber nach dem Lesen der Kunst der Unix-Programmierung bin ich mir nicht sicher, ob sie wirklich sind gute Wahl.Sind Nachrichtenwarteschlangen in Linux veraltet?

http://www.faqs.org/docs/artu/ch07s02.html#id2922148

Die obere, message-passing Schicht von System V IPC hat außer Gebrauch weitgehend gefallen. Die untere Schicht, die aus gemeinsam genutztem Speicher und Semaphoren besteht, hat immer noch bedeutende Anwendungen unter Umständen, in denen man eine gegenseitige Ausschließungssperre und eine globale gemeinsame Datennutzung zwischen Prozessen, die auf derselben Maschine laufen, durchführen muss. Diese System V-Shared-Memory-Funktionen wurden zur POSIX Shared-Memory-API, die unter Linux unterstützt wird, den BSDs, MacOS X und Windows, aber nicht zu klassischem MacOS.

http://www.faqs.org/docs/artu/ch07s03.html#id2923376

Die System V IPC-Einrichtungen sind in Linux und anderen modernen Unix-Varianten. Da sie jedoch ein Legacy-Feature sind, werden sie nicht sehr oft ausgeübt. Die Linux-Version ist seit Mitte 2003 immer noch mit Fehlern behaftet. Niemand scheint sich genug darum zu kümmern, sie zu reparieren.

Sind die System V-Nachrichtenwarteschlangen in neueren Linux-Versionen weiterhin fehlerhaft? Ich bin mir nicht sicher, ob der Autor bedeutet, dass POSIX-Nachrichtenwarteschlangen in Ordnung sein sollten?

Es scheint, dass Sockets die bevorzugte IPC für fast alles (?) Sind, aber ich kann nicht sehen, wie es sehr einfach wäre, Nachrichtenwarteschlangen mit Sockets oder etwas anderes zu implementieren. Oder denke ich zu komplex?

Ich weiß nicht, ob es relevant ist, dass ich mit Embedded Linux arbeite?

Antwort

56

Persönlich bin ich ziemlich gern Message Queues und denke, dass sie wohl die am wenigsten ausgelasteten IPC in der Unix-Welt sind. Sie sind schnell und einfach zu bedienen.

Ein paar Gedanken:

  • Ein Teil davon ist nur Mode. Alte Dinge werden wieder neu. Fügen Sie einen glänzenden Do-Dad auf Nachrichtenwarteschlangen hinzu und sie werden nächstes Jahr die neueste und heißeste Sache sein. Sehen Sie sich Google Chrome an, indem Sie separate Prozesse anstelle von Threads für die Registerkarten verwenden. Plötzlich sind die Leute begeistert, dass wenn eine Registerkarte abstürzt, sie nicht den gesamten Browser zum Absturz bringt.

  • Shared Memory hat etwas von einem He-Man Halo darüber. Sie sind kein "echter" Programmierer, wenn Sie diesen letzten Zyklus nicht aus der Maschine herauspressen und MQs marginal weniger effizient sind. Für viele, wenn nicht die meisten Apps ist es völliger Unsinn, aber manchmal ist es schwer, eine Denkweise zu durchbrechen, wenn sie einmal greift.

  • MQs sind wirklich nicht geeignet für Anwendungen mit unbegrenzten Daten. Stream-orientierte Mechanismen wie Pipes oder Sockets sind einfach zu bedienen.

  • Die System V-Varianten sind wirklich in Ungnade gefallen. In der Regel gehen Sie mit POSIX-Versionen von IPC, wenn Sie können.

+0

7 Jahre später .. hoffentlich ist es nicht zu viel um noch etwas relevant zu sein: Ich wundere mich über die Standardeinstellungen von Nachrichtenwarteschlangen auf 'Ubuntu 14.04',' linux 3.13 ', nämlich' cat/proc/sys/fs/mqueue/msg_max' listet 10 (Nachrichten in einer Warteschlange) auf und '/ proc/sys/fs/mqueue/msgsize_max' ist 8192 (Bytes) - sie sind merkwürdig klein. Gibt es einen strengen Grund für diese Vorgaben oder sind sie nur alt? (Der 'man mq_overview' sagt, dass die harte Grenze von msg_max etwa 32768 ist, was ziemlich hoch ist.) Ich möchte nicht eine unendliche Stream-artige Warteschlange erstellen, sondern ist 100-1000 in 'msg_max' ok? – xealits

10

Ich habe eigentlich keine POSIX-Nachrichtenwarteschlangen verwendet, weil ich immer die Option offen lassen möchte, meine Nachrichten über ein Netzwerk zu verteilen. In diesem Sinne könnten Sie eine robustere Message-Passing-Schnittstelle wie zeromq oder etwas, das AMQP implementiert implementieren.

Eines der schönen Dinge an 0mq ist, dass wenn es aus dem gleichen Prozessraum in einer Multithread-App verwendet wird, es einen Lockless Zero-Copy-Mechanismus verwendet, der ziemlich schnell ist. Trotzdem können Sie die gleiche Schnittstelle verwenden, um Nachrichten auch über ein Netzwerk zu übertragen.

11

Ja, ich denke, dass Nachrichtenwarteschlangen für einige Anwendungen geeignet sind. POSIX-Nachrichtenwarteschlangen bieten eine schönere Schnittstelle, insbesondere geben Sie Ihren Warteschlangen Namen anstelle von IDs, was sehr nützlich für die Fehlerdiagnose ist (macht es einfacher zu sehen, welches das ist).

Linux ermöglicht es Ihnen, die POSIX-Nachrichtenwarteschlangen als Dateisystem zu mounten und sie mit "ls" zu sehen, löschen Sie sie mit "rm", was auch ziemlich praktisch ist (System V hängt von den klobigen "ipcs" und "ipcrm" -Befehlen ab)

+0

Diese Funktion ist auch für UNIX-Datagramm-Sockets verfügbar. Ich kann Datagramm-Socket an eine Datei binden und auf die gleiche Weise wie die POSIX-Nachrichtenwarteschlange empfangen. Ich kann sogar 'netcat' verwenden, um Testdaten an die Datagramm-Socket-Datei zu senden. – shuva

1

größten Nachteile von POSIX-Nachrichtenwarteschlange.

  • POSIX-Nachrichtenwarteschlange nicht eine Anforderung macht mit select() kompatibel zu sein (es mit select() in Linux funktioniert, aber nicht in Qnx System)
  • Es hat Überraschungen.

Unix Datagramm Socket macht die gleiche Aufgabe der POSIX-Nachrichtenwarteschlange. Und Unix-Datagramm-Socket funktioniert in Socket-Ebene. Es ist möglich, es mit select()/poll() oder anderen IO-Wait-Methoden zu verwenden. Die Verwendung von select()/poll() hat den Vorteil, ein ereignisbasiertes System zu entwerfen. Es ist möglich, eine Busy-Schleife auf diese Weise zu vermeiden.

Es gibt Überraschung in der Nachrichtenwarteschlange. Denken Sie an mq_notify(). Es wird verwendet, um ein Empfangsereignis zu erhalten. Es klingt, als könnten wir etwas über die Nachrichtenwarteschlange mitteilen. Aber es registriert sich tatsächlich zur Benachrichtigung, anstatt irgendetwas zu melden.

mehr Überraschung über mq_notify() ist, dass es nach jedem mq_receive() genannt werden muss, die eine Rennbedingung verursachen kann (wenn ein anderer Prozess/Thread Anruf mq_send() zwischen dem Ruf und mq_receive()mq_notify()).

Und es hat eine ganze Reihe von mit ihrer eigenen Definition, die redundant und in einigen Fällen inkonsistent mit Socket open(),send(),recv() and close() Methode Spezifikation ist.

Ich glaube nicht, Nachrichtenwarteschlange sollte für die Synchronisation verwendet werden. eventfd und signalfd sind dafür geeignet.

Aber es hat einige Echtzeit-Unterstützung. Es hat Prioritätsmerkmale.

Messages are placed on the queue in decreasing order of priority, with newer messages of the same priority being placed after older messages with the same priority. 

Aber diese Priorität ist für den Sockel als Out-of-Band-Daten auch zur Verfügung!

Schließlich ist für mich, POSIX-Nachrichtenwarteschlange eine Legacy-API. Ich bevorzuge immer Unix-Datagram-Socket statt POSIX-Nachrichtenwarteschlange.

Verwandte Themen