1

假设我们使用fopen()和从收到的文件指针打开一个文件,使用fileno(). 然后我们从这个文件中做很多(>10^8)随机read()的相对小的块,大小在 4Bytes 到 10KBytes 之间:

如果read()文件errno系统是

  1. ext3

  2. NFS

  3. OCFS2

  4. 2 和 3 的组合(OCFS2通过NFS

?

我的读数给了我一个结论,它不应该是 1. (如果文件没有O_NONBLOCK设置,如果ext3有可能设置它)但对于其他三个(2., 3., 4.)我不确定.

(顺便说一句:我可以假设O_NONBLOCK在任何情况下都没有设置为默认值吗?)

之所以出现这个问题,是因为我观察到read()s 返回的字节数少于errno案例 4 中未设置的请求。

通过测试深入研究的问题是这种行为发生在 <1/1000000000 的情况下...... - 这仍然太频繁了:-}

更新:平均文件大小在几 TBytes 和大约 1GByte 之间。

4

2 回答 2

1

您不应该假设 read() 不会返回比任何文件系统请求的字节少。在大读取的情况下尤其如此,因为 POSIX.1 表明大于 SSIZE_MAX 的大小的 read() 行为取决于实现。在我现在使用的这个主流 Unix 机器上,SSIZE_MAX 是 32767 字节。read() 今天总是返回全额的事实并不意味着它将来会。

一个可能的原因可能是将来 I/O 优先级在内核中更加充实。例如,您正尝试从与另一个更高优先级进程相同的设备读取数据,如果您的进程没有导致磁头移动远离其他进程想要的扇区,则其他进程将获得更好的吞吐量。内核可能会选择给你的 read() 一个简短的计数来让你暂时离开,而不是继续进行低效的交错块读取。 为了 I/O 效率,已经做了一些奇怪的事情。不被禁止的往往变成强制性的。

于 2012-04-16T18:07:56.717 回答
0

我们解决了描述为read()从位于NFS挂载上的文件读取时返回的字节数少于请求的问题,指向OCFS2文件系统(我的问题中的案例 4)。

事实上,使用上述设置,read()文件描述符上的此类 s 有时返回的字节数少于请求的字节数,而无需errno设置。

要读取所有数据,只需read()一次又一次地读取,直到读取所请求的数据量。

此外,这样的设置有时会read()导致失败EIO,即使这样,简单的read()也会导致成功并且数据到达。

我的结论:通过OCFS2via读取文件的行为类似于从套接字读取NFS,这与http://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html的规范不一致:read()read()read()

尝试读取支持非阻塞读取且当前没有可用数据的文件(管道或 FIFO 除外)时:

如果设置了 O_NONBLOCK,read() 将返回 -1 并将 errno 设置为 [EAGAIN]。

如果 O_NONBLOCK 被清除,read() 将阻塞调用线程,直到某些数据可用。

不用说我们从未尝试过,甚至没有想过O_NONBLOCK为有问题的文件描述符设置。

于 2012-07-06T18:55:21.750 回答