POSIX / UNIX: So schließen Sie einen Dateideskriptor zuverlässig

Problem

Nach einem close () - Systemaufruf, der mit EINTR oder EIO fehlschlägt, ist nicht angegeben, ob die Datei geschlossen wurde. http: //pubs.opengroup.org/onlinepubs/9699919799) Bei Multithread-Anwendungen werden beim erneuten Versuch des Schließens möglicherweise nicht verwandte Dateien geschlossen, die von anderen Threads geöffnet wurden. Wenn Sie das Schließen nicht wiederholen, können sich unbrauchbare offene Dateideskriptoren häufen. Eine saubere Lösung könnte das Aufrufen von fstat () für den frisch geschlossenen Dateideskriptor und einen recht komplexen Sperrmechanismus beinhalten. Es kann auch eine Option sein, alle Aufrufe zum Öffnen / Schließen / Akzeptieren / ... mit einem einzigen Mutex zu serialisieren.

Diese Lösungen berücksichtigen nicht, dass Bibliotheksfunktionen Dateien möglicherweise auf unkontrollierte Weise selbstständig öffnen und schließen, z. B. bei einigen Implementierungen von std :: thread :: hardware_concurrency (), die Dateien im Dateisystem / proc öffnen.

Dateistreams wie im C ++ - Standardabschnitt [file.streams] sind keine Option.

Gibt es einen einfachen und zuverlässigen Mechanismus zum Schließen von Dateien, wenn mehrere Threads vorhanden sind?

edits:

Reguläre Dateien: Während sich die meiste Zeit keine unbrauchbaren offenen Dateideskriptoren ansammeln, können zwei Bedingungen das Problem auslösen: 1. Signale, die von Malware mit hoher Häufigkeit ausgegeben werden 2. Netzwerkdateisysteme, die die Verbindung verlieren, bevor die Caches geleert werden.

Sockets: Laut Stevens / Fenner / Rudoff, wenn die Socket-Option SO_LINGER in einem Dateideskriptor festgelegt ist, der sich auf einen verbundenen Socket bezieht, und während eines Schließens (), läuft der Timer ab, bevor die FIN-ACK-Abschaltsequenz abgeschlossen ist, close () scheitert als Teil des allgemeinen Verfahrens. Linux zeigt dieses Verhalten nicht, FreeBSD jedoch und setzt errno ebenfalls auf EAGAIN. Soweit ich weiß, ist in diesem Fall nicht angegeben, ob der Dateideskriptor ungültig ist. C ++ Code zum Testen des Verhaltens:http: //www.longhaulmail.de/misc/close.tx Der dort ausgegebene Testcode sieht für mich wie eine Racebedingung in FreeBSD aus. Wenn nicht, warum nicht?

Möglicherweise erwägt einer, Signale während eines Anrufs zu sperren, um zu schließen ().

Antworten auf die Frage(6)

Ihre Antwort auf die Frage