Ich verstehe nicht, warum Pipes
als unsicher bezeichnet wird, wenn mehrere Absender vorhanden sind und Empfänger.
Wie der folgende Code mit Queues
in Code umgewandelt werden kann, wenn dies der Fall ist Fall ? Queues
wirft EOFError
beim Schließen nicht, sodass meine Prozesse nicht stoppen können. Sollte ich endlos 'Poison'-Nachrichten senden, um sie anzuhalten (auf diese Weise bin ich sicher, dass alle meine Prozesse mindestens ein Gift erhalten)?
Ich möchte die Pipe p1
offen halten, bis ich mich anders entscheide (hier ist es, wenn ich die 10 Nachrichten gesendet habe).
Im Wesentlichen besteht das Problem darin, dass Pipe
ein dünner Wrapper um ein plattformdefiniertes Pipe-Objekt ist. recv
empfängt einfach wiederholt einen Puffer von Bytes, bis ein vollständiges Python-Objekt erhalten wird. Wenn zwei Threads oder Prozesse recv
für dieselbe Pipe verwenden, können die Reads ineinander verschachtelt werden, wodurch jeder Prozess mit einem halben gebeizten Objekt belassen wird und somit die Daten korrumpieren. Queue
s führt eine korrekte Synchronisation zwischen Prozessen auf Kosten von mehr Komplexität durch.
Wie die multiprocessing
-Dokumentation es ausdrückt:
Beachten Sie, dass Daten in einer Pipe beschädigt werden können, wenn zwei Prozesse (oder Threads) gleichzeitig versuchen, von demselben Ende der Pipe zu lesen oder in dasselbe zu schreiben. Natürlich gibt es keine Gefahr der Verfälschung durch Prozesse, bei denen verschiedene Enden der Rohrleitung gleichzeitig verwendet werden.
Sie müssen nicht endlos Giftpillen senden; eine pro Arbeiter ist alles was du brauchst. Jeder Arbeiter nimmt genau eine Giftpille auf, bevor er aussteigt. Es besteht also keine Gefahr, dass ein Arbeiter die Nachricht irgendwie verfehlt.
Sie sollten auch in Erwägung ziehen, multiprocessing.Pool
zu verwenden, statt das Modell "Arbeitsprozess" neu zu implementieren - Pool
verfügt über viele Methoden, die das Verteilen von Arbeit über mehrere Threads sehr einfach machen.
Ich verstehe nicht, warum Pipes unsicher sind, wenn mehrere Sender und Empfänger vorhanden sind.
Denken Sie daran, dass Sie gleichzeitig Wasser aus einer Quelle A und B in ein Rohr geben. Am anderen Ende der Leitung wird es unmöglich sein herauszufinden, welcher Teil des Wassers von A oder B kam, oder? :)
Eine Pipe transportiert einen Datenstrom auf Byte-Ebene. Ohne ein Kommunikationsprotokoll darüber weiß es nicht, was eine Nachricht ist und kann daher die Nachrichtenintegrität nicht sicherstellen. Daher ist es nicht nur unsicher, Pipes mit mehreren Sendern zu verwenden. Dies ist ein wesentlicher Konstruktionsfehler und wird höchstwahrscheinlich zu Kommunikationsproblemen führen.
Warteschlangen sind jedoch auf einer höheren Ebene implementiert. Sie sind für die Kommunikation von Nachrichten (oder auch von abstrakten Objekten) vorgesehen. Warteschlangen dienen dazu, eine Nachricht / ein Objekt eigenständig zu halten. Mehrere Quellen können Objekte in eine Warteschlange stellen und mehrere Benutzer können diese Objekte ziehen, während sie 100% sicher sind, dass alles, was als Einheit in die Warteschlange gelangt, auch als Einheit daraus hervorgeht.
Nach einiger Zeit bearbeiten:
Ich sollte hinzufügen, dass im Byte-Stream alle Bytes in der gleichen Reihenfolge wie gesendet (garantiert) abgerufen werden. Das Problem mit mehreren Absendern besteht darin, dass die Sendefolge (die Reihenfolge der Eingabe) möglicherweise bereits unklar oder zufällig ist, d. H. Mehrere Streams könnten sich in unvorhersehbarer Weise vermischen.
Eine übliche Warteschlangenimplementierung garantiert, dass einzelne Nachrichten intakt bleiben, auch wenn mehrere Absender vorhanden sind. Nachrichten werden in der Reihenfolge, wie sie gesendet wird, ebenfalls abgerufen. Bei mehreren konkurrierenden Absendern und ohne weitere Synchronisationsmechanismen gibt es jedoch wiederum keine Garantie über die Reihenfolge der Eingangsnachrichten.
Tags und Links python pipe multiprocessing unsafe