inotify是否同步排队事件?

问题描述 投票:1回答:2

我正在尝试使用inotify来监视文件系统修改。特别是我试图在一些预先配置的目录中捕获文件的所有更新。

当我试图用SIGTERM关闭应用程序时出现问题。我希望在此之前处理所有修改。

问题:如果唯一进行文件修改的过程(writeing / mving)终止,那么可靠地说,如果FIONREAD ioctl返回0,那么所有修改都是从inotify文件描述符中检索的。 The documentation指定:

FIONREAD ioctl(2)返回可从inotify文件描述符中读取的字节数。

所以我假设如果在进行所有修改的进程关闭之后队列中没有事件,那么从inotify描述符中读取所有事件并且之后没有人会到达。

c linux inotify
2个回答
3
投票

我强烈建议你使用signalfd,请参阅this man page

使用此信号沿管道传送,而不是异步运行信号操作。这样你可以使用像select()epoll()这样的反应器来等待inotify管道和signalfd()文件描述符,让你在实际读取来自fd的信号并处理它时整齐地管理。

并且,因为您在程序的主循环内同步处理信号而不是异步信号动作,所以在处理信号时可以调用的函数没有限制。

在我看来,signalfd()远远超过处理信号的恶劣方式。唯一的小缺点是(AFAIK)不能移植到其他* nixes。


3
投票

在这个问题和接受的答案中,有几件事情被混淆了。

回答问题的核心:

如果正在更改已监视位置中的文件的唯一进程已终止,则可以在inotify队列中没有其他事件时终止。您可以通过检查问题中提到的FIONREAD来安全地检查大小。为了使其不会错过任何事件,您需要确定变异过程已经通过其他方式完成;这个的关键方面是你不想在变异过程完成之前完成处理inotify队列,并且你的inotify过程已经收到了SIGTERM

但是,如果您不知道其他进程是否已完成,但是想要确保直到当前时间点的事件(例如:检测到SIGTERM时)已经处理完毕,您将需要采用类似于在watchman中使用的。这个概念是当您要求终止主进程时,您将在监视目录中创建一个带有魔术名称的特殊标记文件。然后,您将继续处理来自inotify队列的事件,直到您看到您的魔术文件名;此时,您可以知道魔术文件创建之前的所有事件都已被消耗。这里有关于这种技术的更多信息:https://facebook.github.io/watchman/docs/cookies.html(免责声明:我是守望者的创造者)

关于signalfd与传统信号处理的讨论与这个问题的时序方面是正交的:你当然可以使用原始的posix信号处理接口并设置一个全局变量来表示已收到SIGTERM。它不会改变任何有关inotify事件的顺序或时间的信息,因此在实现时请随意使用您喜欢的任何方法。

© www.soinside.com 2019 - 2024. All rights reserved.