POSIX/UNIX:如何可靠地关闭文件描述符 [英] POSIX/UNIX: How to reliably close a file descriptor
问题描述
在因EINTR或EIO失败的close()系统调用之后,未指定文件是否已关闭. ( http://pubs.opengroup.org/onlinepubs/9699919799/) 在多线程应用程序中 重试关闭可能会关闭其他线程打开的不相关文件.不重试关闭可能会导致无法使用的打开文件描述符堆积.一个干净的解决方案可能涉及在新近关闭的文件描述符上调用fstat()和一个非常复杂的锁定机制. 同样,可以使用单个互斥体序列化所有打开/关闭/接受/...调用.
After a close() syscall that fails with EINTR or EIO it is unspecified whether the file has been closed. (http://pubs.opengroup.org/onlinepubs/9699919799/) In multi-threaded applications, retrying the close may close unrelated files opened by other threads. Not retrying the close may result in unusable open file descriptors piling up. A clean solution might involve invoking fstat() on the freshly closed file descriptor and a quite complex locking mechanism. Also, serializing all open/close/accept/... invocations with a single mutex may be an option.
这些解决方案没有考虑到 库函数可能会以无法控制的方式自行打开和关闭文件,例如std :: thread :: hardware_concurrency()的某些实现会打开/proc文件系统中的文件.
These solutions do not take into account that library functions may open and close files on their own in an uncontrollable way, e.g., some implementations of std::thread::hardware_concurrency() open files in the /proc filesystem.
[file.streams] C ++标准部分中的文件流不是一个选择.
File Streams as in the [file.streams] C++ standard section are not an option.
是否存在一种简单可靠的机制来在存在多个线程的情况下关闭文件?
Is there a simple and reliable mechanism to close files in the presence of multiple threads?
常规文件: 尽管大多数情况下不会累积不可用的打开文件描述符,但是有两种情况可能会触发此问题: 1.某些恶意软件高频发射的信号 2.在刷新缓存之前失去连接的网络文件系统.
Regular Files: While most of the time there will be no unusable open file descriptors accumulating, two conditions might trigger the problem: 1. Signals emitted at high frequency by some malware 2. Network file systems that lose connection before caches are flushed.
套接字:根据Stevens/Fenner/Rudoff的说法,如果在引用连接套接字的文件描述符上设置了套接字选项SO_LINGER,并且在close()期间,计时器将在FIN-ACK关闭序列完成之前结束,请关闭()作为通用过程的一部分失败. Linux不会显示这种行为,但是FreeBSD会显示这种行为,并且还将errno设置为EAGAIN.据我了解,在这种情况下,尚不确定文件描述符是否无效.用于测试行为的C ++代码: http://www.longhaulmail.de/misc/close.txt 在我看来,在那里输出的测试代码看起来像FreeBSD中的竞争条件,如果不是,那为什么呢?
Sockets: According to Stevens/Fenner/Rudoff, if the socket option SO_LINGER is set on a file descriptor referring to a connected socket, and during a close(), the timer elapses before the FIN-ACK shutdown sequence completes, close() fails as part of the common procedure. Linux does not show this behavior, however, FreeBSD does, and also sets errno to EAGAIN. As I understand it, in this case, it is unspecified whether the file descriptor is invalidated. C++ code to test the behavior: http://www.longhaulmail.de/misc/close.txt The test code output there looks like a race condition in FreeBSD to me, if it's not, why not?
有人可能会在调用close()时考虑屏蔽信号.
One might consider bocking signals during calls to close().
推荐答案
此问题已在POSIX中修复为下一期;不幸的是,它的变化太大,无法应用于最新的TC2中.有关最终接受的文本. net/view.php?id = 529"rel =" noreferrer>奥斯汀小组问题#529 .
This issue has been fixed in POSIX for the next issue; unfortunately it's too big a change to have made it into the recent TC2. See the final accepted text for Austin Group Issue #529.
这篇关于POSIX/UNIX:如何可靠地关闭文件描述符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!