Was sind Garantien für gleichzeitige Schreibvorgänge in eine Named Pipe?

32

Ich habe beispielsweise eine Named Pipe wie die folgende erstellt:

mknod myPipe p

Und ich lese aus einem Prozess (zum Beispiel einem Server). Zum Beispiel habe ich den Schwanz benutzt:

tail -f myPipe

Wenn mehrere Client-Prozesse Nachrichten darin schreiben (besteht beispielsweise die echo "msg" >> myPipeMöglichkeit, dass Nachrichten verschachtelt werden, wie folgt:

 <beginning of message1><message2><ending of message1>

Oder ist der Prozess des Schreibens auf Named Pipe atomar?

Rogach
quelle

Antworten:

29

Dies hängt davon ab, wie viel jeder Prozess schreibt (vorausgesetzt, Ihr Betriebssystem ist in dieser Hinsicht POSIX-kompatibel). Von write():

Schreibanforderungen an eine Pipe oder einen FIFO werden mit folgenden Ausnahmen wie eine reguläre Datei behandelt:
[...]

  • Schreibanforderungen von {PIPE_BUF} Bytes oder weniger dürfen nicht mit Daten von anderen Prozessen verschachtelt werden, die Schreibvorgänge auf derselben Pipe ausführen . Bei Schreibvorgängen mit mehr als {PIPE_BUF} Bytes können Daten an beliebigen Grenzen mit Schreibvorgängen anderer Prozesse verschachtelt sein, unabhängig davon, ob das O_NONBLOCK-Flag der Dateistatus-Flags gesetzt ist oder nicht.

Auch im Abschnitt Begründung zu Pipes und FIFOs:

  • Atomar / Nichtatomar : Ein Schreibvorgang ist atomar, wenn die gesamte in einer Operation geschriebene Menge nicht mit Daten aus einem anderen Prozess verschachtelt ist. Dies ist nützlich, wenn mehrere Schreiber Daten an einen einzelnen Leser senden. Anwendungen müssen wissen, wie groß eine Schreibanforderung voraussichtlich atomar ausgeführt werden kann. Dieses Maximum heißt {PIPE_BUF}. In diesem Band von POSIX.1-2008 wird nicht angegeben, ob Schreibanforderungen für mehr als {PIPE_BUF} Bytes atomar sind, es ist jedoch erforderlich, dass Schreibvorgänge für {PIPE_BUF} oder weniger Bytes atomar sind.

Der Wert if PIPE_BUFwird von jeder Implementierung definiert, das Minimum beträgt jedoch 512 Byte (siehe limits.h). Unter Linux sind es 4096 Bytes (siehe pipe(7)).

Matte
quelle
5
PIPE_BUF muss übrigens mindestens 512 sein. Beachten Sie, dass Sie auch sicherstellen müssen, dass Ihr Prozess tatsächlich jede Zeile in einem einzigen Schreibaufruf darauf schreibt. Wenn Sie die Zeilenpufferung ( setvbuf(stdout, NULL, _IOLBF,512)) aktivieren, müssen Sie keine Low-Level-Funktionen verwenden.
Random832
Hier ist eine Tabelle der beobachteten PIPE_BUFWerte auf gängigen Unix-Systemen: ar.to/notes/posix#pipe-buf
Arto Bendiken
Ich verstehe nicht, wie Sockets gemultiplext werden können ... aber Named Pipes können nicht? alles unter unix ist nur eine datei oder? lulz
Alexander Mills
@AlexanderMills: Ich verstehe Ihren Kommentar nicht
Mat
1
@AlexanderMills: Nein, das ist der Mindestwert
Mat