假设我们使用fopen()
打开了一个文件,并从收到的文件指针中使用fileno()
获取文件描述符。然后我们做了很多(> 10 ^ 8)随机read()
的相对较小的块,从这个文件大小为4Bytes到10KBytes:
如果文件系统是
,那么read()
的预期行为可能会返回更少的字节然后请求,而不设置errno
ext3
NFS
OCFS2
2和3的组合(OCFS2
通过NFS
)
我的阅读材料给了我一个结论,它不应该是1.(如果文件没有O_NONBLOCK
设置,如果ext3
可以设置它,那么对于其他三个( 2.,3.,4。)我不确定。
(顺便说一句:我可以假设O_NONBLOCK
在任何情况下都没有设置为默认值吗?)
出现这个问题是因为我观察到read()
返回的字节数较少,然后在案例4中没有errno
的情况下请求。
通过测试来解决这个问题的问题是,这种行为发生在< 1/1000000000例...... - 这仍然太频繁了: - }
更新:平均文件大小介于TBytes和1GByte之间。
答案 0 :(得分:1)
您不应该假设read()不会返回比任何文件系统请求的字节数更少的字节。在大型读取的情况下尤其如此,因为POSIX.1指示大于SSIZE_MAX的大小的read()行为是依赖于实现的。在我现在使用的这个主流Unix盒子上,SSIZE_MAX是32767字节。 read()总是在今天返回全部金额的事实并不意味着它将来会发生。
一个可能的原因可能是未来内核中的I / O优先级更加充实。例如。您试图从同一设备读取另一个更高优先级的进程,如果您的进程没有导致磁头移动远离其他进程所需的扇区,则另一个进程将获得更好的吞吐量。内核可能会选择给你的read()一个简短的计数,让你暂时停止,而不是继续进行低效的交错块读取。为了I / O效率,Stranger things have been done。什么是不被禁止的通常是强制性的。
答案 1 :(得分:0)
我们解决了描述为read()
返回较少字节的问题,然后从位于NFS
mount上的文件读取请求,指向OCFS2
文件系统(我的情况4)问题)。
事实上,使用上面提到的设置,文件描述符上的这样的read()
有时会返回更少的字节然后请求,而不设置errno
。
要读取所有数据就像一次又一次read()
一样简单,直到读取了所请求的数据量为止。
此外,此类设置有时会导致read()
因EIO
而失败,即使这样,简单的重新read()
也会导致成功并且数据到达。
我的结论:通过OCFS2
通过NFS
进行阅读,使文件read()
的行为类似read()
来自套接字,这与read()
的规范不一致http://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html:
尝试读取文件(管道或FIFO除外)时 支持非阻塞读取,并且当前没有可用的数据:
如果设置了O_NONBLOCK,则read()将返回-1并将errno设置为[EAGAIN]。
如果O_NONBLOCK被清除,read()将阻塞调用线程,直到某些数据可用。
无需说我们从未尝试过,甚至没有想过为有问题的文件描述符设置O_NONBLOCK
。