POSIX / UNIX: как надежно закрыть дескриптор файла

Проблема:

После системного вызова close (), который завершается неудачно с EINTR или EIO, не указывается, был ли файл закрыт. (http://pubs.opengroup.org/onlinepubs/9699919799/) В многопоточных приложениях повторное закрытие может закрыть несвязанные файлы, открытые другими потоками. Отказ от повторного закрытия может привести к тому, что дескрипторы открытых файлов будут накапливаться. Чистое решение может включать вызов fstat () для только что закрытого файлового дескриптора и довольно сложный механизм блокировки. Кроме того, сериализация всех вызовов open / close / accept / ... с одним мьютексом может быть опцией.

Эти решения не учитывают, что библиотечные функции могут самостоятельно открывать и закрывать файлы неуправляемым способом, например, некоторые реализации открытых файлов std :: thread :: hardware_concurrency () в файловой системе / proc.

Файловые потоки, как в стандартном разделе C ++ [file.streams], не являются опцией.

Существует ли простой и надежный механизм закрытия файлов при наличии нескольких потоков?

редактирует:

Обычные файлы. Хотя в большинстве случаев не будет накапливаться неиспользуемых дескрипторов открытых файлов, проблема может быть вызвана двумя условиями: 1. Сигналы, испускаемые с высокой частотой некоторыми вредоносными программами.

Сокеты: согласно Stevens / Fenner / Rudoff, если опция дескриптора SO_LINGER установлена ​​в файловом дескрипторе, относящемся к подключенному сокету, и во время закрытия () таймер истекает до завершения последовательности выключения FIN-ACK, завершение сбоя () как часть общей процедуры. Linux не показывает такое поведение, однако, FreeBSD, а также устанавливает errno на EAGAIN. Насколько я понимаю, в этом случае не определено, является ли дескриптор файла недействительным. Код C ++ для проверки поведения:http://www.longhaulmail.de/misc/close.txt Вывод тестового кода для меня выглядит как состояние гонки во FreeBSD, если нет, то почему?

Можно рассмотреть сигналы блокировки во время вызовов close ().