2008-09-29 7 views
11

Ich habe eine popen() -Funktion, die "tail -f sometextfile" ausführt. Solange Daten im Filestream vorhanden sind, kann ich die Daten natürlich über fgets() abrufen. Wenn nun keine neuen Daten vom Tail kommen, hängt fgets(). Ich habe ferror() und feof() vergeblich versucht. Wie kann ich sicherstellen, dass fgets() nicht versucht, Daten zu lesen, wenn sich im Dateistream nichts Neues befindet?Wie verhindert man, dass Fgets blockiert werden, wenn der Datenstrom keine neuen Daten hat?

Einer der Vorschläge war wählen(). Da dies für Windows Platform ist, scheint select nicht zu funktionieren, da anonyme Pipes anscheinend nicht funktionieren (siehe this post).

Antwort

0

I würden Sie POSIX-Funktionen für IO statt denen der C-Bibliothek verwenden, könnten Sie select oder poll verwenden.

0

Sie können stattdessen versuchen, einige Textdatei mit Low-Level-IO-Funktionen (open(), read() usw.) zu lesen, wie Tail selbst tut. Wenn nichts mehr zu lesen ist, gibt read() null zurück, versucht aber im Gegensatz zu FILE * -Funktionen beim nächsten Mal mehr zu lesen.

+0

Dies war nur ein Beispiel. Die Idee besteht darin, Daten zu ziehen und sie durch ein Mutex-Objekt an eine Flash-Instanz zu übergeben. – SinisterDex

15

fgets() ist eine Blockierung lesen, es soll warten, bis Daten verfügbar sind, wenn keine Daten vorhanden sind.

Sie möchten asynchrone E/A mit select(), poll() oder ausführen. Führen Sie dann einen Lesevorgang aus dem Dateideskriptor durch, wenn Daten verfügbar sind.

Diese Funktionen verwenden die Dateibeschreibung des FILE* Griff, abgerufen durch: int fd = fileno(f);

+1

Definiere definitiv select() - Wenn du eine FILE * hast und einen Dateideskriptor brauchst, benutze fileno(). Wenn Sie einen Dateideskriptor haben und eine FILE * benötigen, verwenden Sie fdopen(). – plinth

+0

Guter Vorschlag, bearbeitet, um fileno einzuschließen. – Sufian

+0

Leider denke ich, dass select() nicht auf Pipes unter Windows funktioniert. – Roddy

25

In Linux (oder einem Unix-y OS) können Sie die zugrunde liegende Dateideskriptors von popen verwendet markieren() nicht zu sein Blockierung.

#include <fcntl.h> 

FILE *proc = popen("tail -f /tmp/test.txt", "r"); 
int fd = fileno(proc); 

int flags; 
flags = fcntl(fd, F_GETFL, 0); 
flags |= O_NONBLOCK; 
fcntl(fd, F_SETFL, flags); 

Wenn kein Eingang vorhanden ist, fgets wird mit errno Satz zu EWOULDBLOCK NULL zurück.

0

Ich löste meine Probleme mit Hilfe von Threads, speziell _beginthread , _beginthreadex.

+1

Wenn Sie Ihre eigene Frage beantwortet haben, stellen Sie dies bitte als Antwort ein und poste möglicherweise Ihre Lösung. –

Verwandte Themen