POSIX/UNIX:如何可靠地关闭文件描述符

Hei*_*och 12 c++ unix multithreading freebsd

问题:

在使用EINTR或EIO失败的close()系统调用之后,未指定文件是否已关闭.(http://pubs.opengroup.org/onlinepubs/9699919799/)在多线程应用程序中,重试关闭可能会关闭其他线程打开的不相关文件.不重试关闭可能导致无法打开的文件描述符堆积.一个干净的解决方案可能涉及在新近关闭的文件描述符上调用fstat()和一个非常复杂的锁定机制.此外,使用单个互斥锁序列化所有打开/关闭/接受/ ...调用可能是一种选择.

这些解决方案没有考虑库函数可能以不可控制的方式打开和关闭文件,例如,/ proc文件系统中的std :: thread :: hardware_concurrency()的一些实现打开文件.

文件流在[file.streams] C++标准部分中不是一个选项.

是否有一个简单而可靠的机制来在存在多个线程的情况下关闭文件?


编辑:

常规文件:虽然大多数情况下不会有不可用的打开文件描述符累积,但有两个条件可能会触发问题:1.某些恶意软件以高频率发出的信号2.刷新缓存之前失去连接的网络文件系统.

套接字:根据Stevens/Fenner/Rudoff的说法,如果套接字选项SO_LINGER设置在引用连接套接字的文件描述符上,并且在close()期间,定时器在FIN-ACK关闭序列完成之前经过,则close()失败作为共同程序的一部分.Linux没有显示这种行为,但FreeBSD会这样做,并且还将errno设置为EAGAIN.据我所知,在这种情况下,未指定文件描述符是否无效.用于测试行为的C++代码:http://www.longhaulmail.de/misc/close.txt那里的测试代码输出看起来像FreeBSD中的竞争条件,如果不是,为什么不呢?

人们可能会在调用close()期间考虑信号.

R..*_*R.. 6

此问题已在POSIX中修复以用于下一期; 不幸的是,进入最近的TC2变化太大了.见最后接受了文本奥斯汀组问题#529.