FIFO-Pipe ist immer in select () lesbar

7

In C Pseudocode:

%Vor%

Der Prozess ruht so lange, wie er von select() ausgelöst wurde, bis ein anderer Prozess in fifo schreibt. Danach wird immer fifo als lesbarer Dateideskriptor gefunden.

Wie vermeidet man dieses Verhalten (nachdem fifo einmal gelesen wurde, wie kann man es als unlesbar finden, bis es einen anderen Schreibvorgang bekommt?)

    
Matoe 30.01.2013, 00:11
quelle

2 Antworten

26

Sie haben diesen FIFO nur als schreibgeschützt geöffnet (O_RDONLY). Wenn kein Schreiber im FIFO ist, erhält das Leseende einen EOF .

Wählen Sie Systemaufruf wird auf EOF zurückgegeben und für jedes EOF , das Sie bearbeiten, wird ein neues EOF angezeigt. Dies ist der Grund für das beobachtete Verhalten.

Um dies zu vermeiden, öffnen Sie diesen FIFO sowohl zum Lesen als auch zum Schreiben (O_RDWR). Dies stellt sicher, dass Sie mindestens einen Schreiber auf dem FIFO haben, also wird es nicht EOF geben und als Ergebnis wird select nicht zurückkehren, wenn nicht jemand in diesen FIFO schreibt.

    
Fox 11.08.2013, 20:47
quelle
3

Die einfache Antwort ist zu lesen, bis read() EWOULDBLOCK (oder EAGAIN ) zurückgibt, oder mit einem Fehler scheißt.

Was Sie sagen, kann einfach nicht passieren, wenn das Betriebssystem (oder die Laufzeit), die Sie verwenden, fehlerhaft ist. Sonst musst du etwas falsch machen. Zum Beispiel verwendet select() levelgetriggerte E / A. Ich denke, dass Sie den Socket wahrscheinlich nicht vollständig leeren, und so zeigt select() immer an, dass noch etwas übrig ist (dies passiert nicht bei flankengetriggerten Ereignisbenachrichtigungen).

Unten ist ein einfaches Beispiel, das zeigt, wie man lesen sollte, bis read() EWOULDBLOCK zurückgibt, um zu vermeiden, dass der Deskriptor im lesbaren Zustand bleibt (Ich habe dies unter OS X kompiliert und getestet und es gibt auch meistens keine Fehlerüberprüfung, aber Sie sollten die Idee bekommen):

%Vor%

Im Grunde bedeutet levelgesteuerter E / A, dass Sie immer benachrichtigt werden, wenn etwas zu lesen ist, obwohl Sie vielleicht schon vorher davon benachrichtigt wurden. Im Gegensatz dazu bedeutet flankengetriggerte E / A, dass Sie nur einmal jedes Mal benachrichtigt werden, wenn neue Daten eintreffen, und es spielt keine Rolle, ob Sie sie lesen oder nicht. select() ist eine levelgesteuerte E / A-Schnittstelle.

Ich hoffe, es hilft. Viel Glück!

    
user405725 30.01.2013 00:33
quelle

Tags und Links