2009-05-15 4 views
6

Ich habe ein Windows-C-Programm, das seine Daten über ein umgeleitet stdin Rohr, Art wie diese bekommt:in den Fenstern, wie nicht-blockierenden stdin zu haben, die ein umgeleiteten Rohr?

./some-data-generator | ./myprogram 

Das Problem ist, dass ich in die Lage sein zu lesen, von stdin in einer nicht blockierenden Weise. Der Grund dafür ist, dass (1) die Eingabe ein Datenstrom ist, und es gibt keine EOF und (2) das Programm muss in der Lage sein, seinen stdin -reading Faden jederzeit abgebrochen werden. fread Blöcke, wenn es keine Daten gibt, so ist es dadurch sehr schwierig.

In Unix ist dies kein Problem, da Sie den Blockierungsmodus eines Dateideskriptors mit fcntl und O_NONBLOCK festlegen können. fcntl ist jedoch nicht in Windows vorhanden.

Ich versuchte SetNamedPipeHandleState mit:

DWORD mode= PIPE_READMODE_BYTE|PIPE_NOWAIT; 
    BOOL ok= SetNamedPipeHandleState(GetStdHandle(STD_INPUT_HANDLE), &mode, NULL, NULL); 
    DWORD err= GetLastError(); 

aber nicht mit ERROR_ACCESS_DENIED (0x5).

Ich bin mir nicht sicher, was anderes zu tun. Ist das wirklich unmöglich (!) Oder ist es nur stark verschleiert? Die Ressourcen im Netz sind für dieses spezielle Problem eher spärlich.

Antwort

3

Die Reihenfolge apprach, überprüfen Sie es eingabebereit ist zu lesen:

  • Für Konsolen-Modus können Sie GetNumberOfConsoleInputEvents() verwenden.
  • Für Rohrumleitung können Sie, wenn der Griff zu einem anonymen Rohr wird nicht funktionieren verwenden PeekNamedPipe()
+0

PeekNamedPipe war das, was ich suchte ... Auf diese Weise können Sie dann ReadFile- nennen, so dass sie nicht blockiert. – paleozogt

1

könnten Sie async I/O verwenden, von dem Griff, wie der ReadFileEx() WIN32 Aufruf zu lesen. Verwenden Sie CancelIo(), um das Lesen ohne Eingabe zu beenden.

Siehe MSDN bei http://msdn.microsoft.com/en-us/library/aa365468(VS.85).aspx

+1

, dass - wie es im Beispiel gibt in der Frage sein wird. Überlappende (asynchrone) E/A ist mit anonymen Pipes nicht möglich. –