2009-02-24 5 views
17

Wenn ich ein Programm habe, das erstellt und versucht, eine Named Pipe mit mkfifo zu öffnen, wie kann ich eine Pipe zum Lesen oder Schreiben öffnen, ohne zu blockieren?Wie führe ich ein nicht-blockierendes fopen auf einer Named Pipe (mkfifo) aus?

Speziell schreibe ich ein C-Programm, das mit oder ohne GUI (in Java geschrieben) ausgeführt werden kann.

Im C-Programm, ich habe die Named Pipes erfolgreich erstellen mkfifo verwenden, aber wenn ich

FILE* in = fopen(PIPE_IN, "r"); /* Where PIPE_IN is the filename*/ 

fopen nicht zurück, bis die GUI zum Beschreiben Rohr öffnet. Was ich tun möchte, ist, dass diese Pipe bereit ist, einmal gelesen zu werden (wenn die GUI beschließt, darauf zu schreiben - ich werde den Dateideskriptor in einen select() -Aufruf setzen. Es ist vernünftig zu erwarten, dass die Java-GUI niemals wirklich gestartet wird, so dass ich mich nicht darauf verlassen kann, das andere Ende der Pipe an einem bestimmten Punkt oder überhaupt zu öffnen.

Ich habe auch eine zweite Leitung zum Schreiben geöffnet, und ich nehme an, dass ich das gleiche Problem haben werde. Außerdem kann ich O_NONBLOCK nicht für eine Ausgabe-Pipe festlegen, die kein Lesegerät besitzt.

Irgendwelche Vorschläge?

(Dies ist auf einem Linux-System läuft)

+0

Müssen Sie die Ausgangsleitung öffnen, bevor Sie() auf die Eingangsleitung feuern? –

+0

@tinkertim - ich nehme an, technisch nicht - ich hatte sie beide in einer Setup-Funktion eingestellt, aber ich könnte nur die Ausgangsleitung zuerst einrichten und dann wählen, warum? – Zxaos

Antwort

12

Sie könnten open() Pfeife O_RDONLY | O_NONBLOCK, und wenn Sie den C-Stream möchten, können Sie es mit fdopen() bekommen. Es kann jedoch ein Problem mit der select() - AFAIK, ein Rohr fd offen zum Lesen, dass kein Schreiber ist immer zum Lesen vorbereitet, und read() gibt 0 zurück, so würde die select() unbegrenzt feuern.

Eine kludgy Weise, das zu überwinden, wäre, die Leitung zu öffnen O_RDWR; das heißt, haben mindestens einen Schreiber (Ihr C++ Programm). Welches würde dein Problem sowieso lösen.

+1

Ich gebe dem Leser eine Chance - aber ich kann O_NONBLOCK nicht auf eine Ausgangsleitung setzen ... – Zxaos

+1

Der POSIX-Standard sagt (von select()): "Ein Deskriptor soll beim Lesen als bereit zum Lesen betrachtet werden zu einer Eingabefunktion mit O_NONBLOCK löschen würde nicht blockieren, ob die Funktion Daten erfolgreich übertragen würde oder nicht. " (POSIX.1: 2008). –

+1

Das Öffnen der Pipe O_RDWR würde zu einem Deadlock führen, wenn das Programm liest (oder schreibt) - es sei denn, es gibt auch einen anderen Prozess, bei dem die Pipe geöffnet ist. –