inotify 是否会在写入开始或完成时触发通知?

Tod*_*eed 13 linux stat files inotify

想象两个进程,一个读取器和一个写入器,通过 ext3 fs 上的常规文件进行通信。ReaderIN_MODIFY对文件有一个 inotify监视。Writer 在一次write()调用中将 1000 个字节写入文件。Reader 获取 inotify 事件,并调用fstat文件。读者看到了什么?

  1. 是否有任何保证 Reader 将至少获得 1000 美元st_size的文件?从我的实验来看,似乎不是。

  2. 有没有保证 Reader 实际上可以read()1000 个字节?

这发生在严重的 I/O 绑定框上。例如,sar显示大约 1 秒的等待时间。在我的情况下,Reader 在调用之前获得 inotify 事件后实际上等待了 10 秒stat,并且得到的结果太小。

我曾希望在文件准备好之前不会传递 inotify 事件。我怀疑实际发生的是 inotify 事件write()在 Writer 中的调用期间触发,并且只要数据准备就绪,系统上的其他进程实际上都可以使用该数据。在这种情况下,10 秒是不够的。

我想我只是想确认内核实际上按照我猜测的方式实现了 inotify。另外,如果有任何选择,可能会改变这种行为?

最后-考虑到这种行为,inotify 的意义何在?无论如何,在您获得事件后,您将不得不轮询文件/目录,直到数据实际可用为止。不妨一直这样做,而忘记 inotify。

*** 编辑 ** * * 好吧,正如经常发生的那样,我看到的行为实际上是有道理的,现在我明白了我真正在做什么。^_^

我实际上是在响应文件所在目录上的 IN_CREATE 事件。所以我实际上是在 stat()'ing 文件以响应文件的创建,不一定是 IN_MODIFY 事件,它可能稍后到达。

我将更改我的代码,以便在收到 IN_CREATE 事件后,我将订阅文件本身的 IN_MODIFY,并且在收到 IN_MODIFY 事件之前我不会实际尝试读取文件。我意识到那里有一个小窗口,我可能会错过对文件的写入,但这对我的应用程序来说是可以接受的,因为在最坏的情况下,文件将在最大秒数后关闭。

Gil*_*il' 6

从我在内核源代码中看到的, inotify 只有在写入完成后才会启动(即您的猜测是错误的)。触发通知后sys_write,在实现write系统调用的函数中只发生了两件事:设置一些调度程序参数,以及更新文件描述符上的位置。这段代码早在2.6.14 就很相似。到通知触发时,文件已经有了新的大小。

检查可能出错的事情:

  • 也许读者收到了以前写的旧通知。
  • 如果读者调用stat然后调用read或反之亦然,则可能会在两者之间发生某些事情。如果您继续追加到文件,调用statfirst 可以保证您能够读取那么远,但是在 reader 调用时可能已经写入了更多数据read,即使它还没有收到 inotify 通知。
  • 仅仅因为 writer 调用write并不意味着内核将写入请求的字符数。在极少数情况下,可以保证任意大小的原子写入。write然而,每个调用都保证是原子的:在某些时候数据还没有写入,然后突然写入了n个字节,其中nwrite调用的返回值。如果您观察到部分写入的文件,则意味着write返回的文件小于其大小参数。

调查正在发生的事情的有用工具包括:

  • strace -tt
  • 审计子系统