C - 从文件中读取() - 阻塞与非阻塞行为

  • 本文关键字:文件 读取 c linux nfs ocfs2
  • 更新时间 :
  • 英文 :


假设我们使用fopen()打开了一个文件,并从收到的文件指针中获取文件描述符,使用fileno() .然后我们做很多(>10^8)相对小块的随机read(),大小在4字节到10KB之间:

errno read()如果文件系统是

  1. ext3

  2. NFS

  3. OCFS2

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

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

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

出现这个问题是因为我观察到read()返回的字节少于请求的字节数,而没有在案例 4 中设置errno

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

更新:平均文件大小介于一些TBytes和大约1GB之间。

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

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

我们解决了描述的问题,即从位于NFS挂载上的文件读取时read()返回更少的字节,然后请求指向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

相关内容

  • 没有找到相关文章

最新更新