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?)
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.
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):
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!
Tags und Links c select file-descriptor fifo