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

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

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

  1. 是否能保证读者能获得至少 1000 美元的st_size文件赔偿?从我的实验来看,似乎不是。

  2. 是否能保证Reader实际上可以读取read()1000字节?

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

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

我想我只是在寻找内核是否确实按照我猜测的方式实现 inotify 的确认。另外,是否有任何选择可能可以改变这种行为?

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

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

我实际上是在响应文件所在目录上的 IN_CREATE 事件。因此,我实际上是在响应文件的创建而对文件进行 stat() 操作,而不一定是 IN_MODIFY 事件,该事件可能稍后到达。

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

答案1

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

检查是否有可能出错的地方:

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

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

  • strace -tt
  • 审计子系统

相关内容