【问题标题】:read() from file return what?从文件中读取()返回什么?
【发布时间】:2018-05-09 15:33:38
【问题描述】:

在以下所有参考资料中:

http://pubs.opengroup.org/onlinepubs/9699919799/

https://linux.die.net/man/3/read

上面写着:

当试图读取一个文件(管道或 FIFO 除外)时, 支持非阻塞读取,目前没有可用数据:

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

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

如果有一些数据,使用 O_NONBLOCK 标志无效 可用。

但谁真正尝试过呢?正如我测试的那样,以上所有情况都会让 read() 返回 0。

不管我这样设置,O_NONBLOCK 似乎都不起作用:

int flags = O_RDONLY;
int mode = S_IRGRP|S_IROTH|S_IRUSR;
int _pbfd = (::open)("123",flags,mode);

或者这样:

int _pbfd = (::open)("123",flags,mode);
int saved_flags = fcntl(_pbfd, F_GETFL);
fcntl(_pbfd, F_SETFL, saved_flags & ~O_NONBLOCK);

【问题讨论】:

  • (::open) 看起来更像是带有不必要括号的 C++,而不是 C。
  • 对我来说,它看起来不像O_NONBLOCK 中的任何一个。第二个明确清除它。
  • 非阻塞 IO 的使用相当广泛,并且已经使用了很长时间。与其假设它不像记录的那样工作,您可能应该得出结论说您没有(正确地)使用它。
  • 该站点man7.org/linux/man-pages/man2/open.2.html 说:“O_NONBLOCK 或 O_NDELAY:.....请注意,此标志对常规文件无效 ....”
  • 除此之外,无论非阻塞模式如何,read() 将返回 0,如果这是您请求的字节数,或者当前文件偏移量位于或超过文件末尾。

标签: c linux io blocking


【解决方案1】:

the POSIX read() specification 中适用的关键部分以粗体显示:

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

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

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

  • 如果有一些可用数据,则使用O_NONBLOCK 标志无效。

必须设计和编写底层文件系统以支持非阻塞读取,而大多数文件系统不支持文件。

不可能知道为什么文件系统开发人员没有编写很多支持O_NONBLOCK(如果有的话...)的文件系统,但很可能是因为它对文件没有用处。文件对象有一个 state - 文件系统知道是否有可用的数据,并且没有外部依赖关系,因为某些数据可能突然以不会影响文件状态的方式出现。

虽然“你已经阅读了整个文件”与“管道中什么都没有(还)”不同,但返回给调用者的信息并没有太大区别。

【讨论】:

  • 好吧,我想你是对的,很多像我这样的文件系统并没有为文件实现“支持非阻塞”。所以这就是为什么 read() 如果读取到文件的尖端总是返回 0。
  • @guangchen POSIX 标准的措辞似乎倒退了——普通文件上的read() 通常是非阻塞的。我认为标准试图说的是“非阻塞读取作为特殊情况”,这意味着设置O_NONBLOCK 的处理方式不同。如上面的 cmets 所述,Linux 明确声明该标志对常规文件没有影响。
猜你喜欢
  • 1970-01-01
  • 2013-05-07
  • 2018-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多