在使用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()期间考虑信号.
假设我们有一个包含N个T类型元素的数组.
T a[N];
Run Code Online (Sandbox Code Playgroud)
根据C++ 14标准,我们在哪些条件下有保证
(char*)(void*)&a[0] + n*sizeof(T) == (char*)(void*)&a[n], (0<=n<N) ?
Run Code Online (Sandbox Code Playgroud)
虽然对于许多类型和实现都是如此,但标准在脚注中以一种模糊的方式提到它:
§5.7.6,脚注85)另一种接近指针算法的方法......
几乎没有迹象表明这种方式被认为等同于标准的方式.对于实施者来说,这可能是一个提示,它暗示了许多符合要求的实现之一.
编辑:
人们低估了这个问题的难度.
这个问题不是关于你在教科书中可以阅读的内容,而是关于你可以通过使用逻辑和理由从C++ 14标准中推断出什么.
如果你使用'连续'或'连续',请说出什么是连续的.
虽然T []和T*密切相关,但它们是抽象,并且T*x N的加法可以通过任何一致的方式实现来定义.
使用指针添加重新排列等式.如果p指向char,则总是使用(§5.7(4))或一元加法定义p + 1,因此我们不会遇到UB.原始包括指针减法,这可能早期导致UB.(char指针只进行比较,而不是解除引用).