3

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

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

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

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

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

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

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

4

2 回答 2

3

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

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

于 2013-01-23T09:30:44.400 回答
2

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

也许没有文件的情况。write(2)的Linux 手册页指出 EWOULDBLOCK 只会为引用套接字的文件描述符返回。

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

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

于 2013-01-24T09:08:10.283 回答