【问题标题】:When does write() to a file return EWOULDBLOCK?文件的 write() 何时返回 EWOULDBLOCK?
【发布时间】:2013-01-06 17:23:53
【问题描述】:

我想经常将数据附加到本地文件系统上的文件中。我想在不阻塞太久的情况下做到这一点,并且不创建任何工作线程。在 Linux 内核 2.6.18 上。

似乎 Linux 上 glibc 的 POSIX AIO 实现创建了一个用户空间线程池并阻塞了这些线程。这很酷,但我可以轻松地剥离我自己的专用文件阻塞线程。

据我了解,Linux 内核 AIO 实现当前在追加时会阻塞。追加是我唯一想做的事情。

我正在考虑使用 O_NONBLOCK 打开文件,然后在 EWOULDBLOCK 处进行一种懒惰的写入,然后再尝试写入。像这样的:

  1. open(pathname, O_CREAT | O_APPEND | O_NONBLOCK);
  2. 调用write(),检查错误EAGAIN | EWOULDBLOCK
  3. 如果EAGAIN | EWOULDBLOCK,则只需保存要写入的数据,稍后再尝试write()

这是个好主意吗?这有什么实际优势吗?如果我是唯一一个对该文件具有打开文件描述符的人,并且我尝试了write()EWOULDBLOCK,那么以后EWOULDBLOCK 的可能性会降低吗?它会不会EWOULDBLOCK?如果我write() 而不是EWOULDBLOCK,这是否意味着write() 会迅速返回?

换句话说,在 Linux 2.6.18 上,在什么情况下,write() 到本地文件会以EWOULDBLOCK 失败?

【问题讨论】:

  • “什么情况...” - 对于文件可能没有。 write(2) 的 Linux 手册页指出 EWOULDBLOCK 只会为引用 socket 的文件描述符返回。
  • @sawdust 哦,我在阅读手册页时错过了这一点。这就是答案。如果您发布它,我会将其标记为答案。

标签: linux asynchronous io linux-kernel filesystems


【解决方案1】:

在......什么情况下......将 write() 到本地文件失败并出现 EWOULDBLOCK

也许没有文件的情况。 Linux man page for write(2) 声明 EWOULDBLOCK 只会为引用 socket 的文件描述符返回。

EAGAIN 或 EWOULDBLOCK
文件描述符 fd 引用一个套接字并且已被标记为非阻塞 (O_NONBLOCK),并且写入会阻塞。 POSIX.1-2001 允许在这种情况下返回任一错误,并且不要求这些常量具有相同的值,因此可移植应用程序应检查这两种可能性。

显然,这种行为与套接字会使用记录锁这一事实有关,而简单文件则不会。

【讨论】:

    【解决方案2】:

    我不确定本地文件系统,但我很确定您在尝试写入已安装文件系统(例如 nfs)上的文件时可以获得 EWOULDBLOCK。这里的问题是,通常你不知道它是否真的是“本地”硬盘,除非你每次创建/打开文件时都特别检查它。如何检查这当然取决于系统。

    即使系统创建了一些额外的线程来进行实际的写入,这个线程也会有一个缓冲区(不会是无限的),所以如果你写得足够快,你可以获得 EWOULDBLOCK。

    【讨论】:

      猜你喜欢
      • 2016-07-08
      • 2011-12-04
      • 1970-01-01
      • 2018-11-19
      • 1970-01-01
      • 2011-02-13
      • 1970-01-01
      • 2016-01-06
      • 2012-01-24
      相关资源
      最近更新 更多