FIFO-pipe ist immer lesbar, im select()
In C-pseudo-code:
while (1) {
fifo = open("fifo", O_RDONLY | O_NONBLOCK);
fd_set read;
FD_SET(fifo, &read);
select(nfds, &read, NULL, NULL, NULL);
}
Den Prozess schläft, als sich-ausgelöst durch die select()
bis ein anderer Prozess schreibt in fifo
. Danach wird es immer finden fifo
als eine lesbare Datei-Deskriptor.
Wie dieses Verhalten zu vermeiden (das ist, nach fifo
wurde einmal gelesen, wie man es als unlesbar wird, bis man es bekommt noch ein schreiben?)
- Also, was willst du auftreten?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ihnen eröffnet, dass FIFO nur Lesen (O_RDONLY), wenn dort ist kein Schriftsteller, der FIFO Lesen, die Ende erhalten Sie eine
EOF
.Wählen Sie system-Aufruf zurück auf
EOF
und für jedenEOF
Sie Griff wird es eine neueEOF
. Dies ist der Grund für das beobachtete Verhalten.Um dies zu vermeiden, öffnen Sie das FIFO zum Lesen und schreiben (O_RDWR). Dies stellt sicher, dass Sie mindestens einen writer haben nach dem FIFO-es gibt also nicht eine
EOF
und als Ergebnis wählen Sie nicht zurückkehren, es sei denn, jemand schreibt, dass FIFO.Ist die einfache Antwort, zu Lesen, bis
read()
zurückEWOULDBLOCK
(oderEAGAIN
), oder craps mit Fehler.Was Sie sagen, einfach nicht passiert, außer das Betriebssystem (bzw. die Laufzeitumgebung), die Sie verwenden, ist buggy. Ansonsten müssen Sie etwas falsch machen. Zum Beispiel
select()
ist die Verwendung von level-triggered-I/O. ich würde denken, dass, wahrscheinlich, Sie werden nicht ablassen, den socket komplett, und soselect()
immer bedeutet, dass Sie etwas Links in es (dies geschieht nicht mit edge-triggered event-Benachrichtigungen).Unten ist ein einfaches Beispiel, das zeigt, wie man Lesen sollte, bis die
read()
zurückEWOULDBLOCK
um zu vermeiden, dass Deskriptor in einem lesbaren Zustand (ich habe Sie kompiliert und getestet auf OS X, und es ist meist auch kein Fehler zu überprüfen, aber Sie sollten Sie bekommen die Idee):Grundsätzlich level-triggered-I/O bedeutet, dass Sie benachrichtigt, wenn es etwas zu Lesen, obwohl Sie möglicherweise nicht benachrichtigt wurden, vor. Auf Gegenteil, edge-triggered-I/O bedeutet, dass Sie immer nur einmal benachrichtigt jedes mal, wenn neue Daten ankommen und es ist egal, ob Sie es Lesen oder nicht.
select()
ist ein level-triggered-I/O-Schnittstelle.Hoffe, es hilft. Viel Glück!
select
gibt, wenn eine Blockierungread
zurückkehren würde, undread
zurück0
(Signalisierung EOF), wenn keiner deine fifo zum schreiben geöffnet. Dein Beispiel-Programm überhaupt nicht, weil es die fifo zum schreiben geöffnet selbst.