合并GCD文件系统事件

时间:2014-12-08 21:20:10

标签: macos cocoa grand-central-dispatch

我有一个实现文件监视服务的类,用于检测我感兴趣的文件何时被我的应用程序以外的其他文件更改。我使用标准技术打开文件(带有O_EVTONLY标志)并将文件描述符绑定到类型为DISPATCH_SOURCE_TYPE_VNODE的Grand Central Dispatch源。当我收到一个事件时,我通过NSNotificationCenter的{​​{1}}通知我的主线程,该线程在我的app委托中调用一个观察者。到现在为止还挺好。它很棒。但是,通常,如果触发事件是属性更改(即postNotificationName:object:userInfo:标志在从DISPATCH_VNODE_ATTRIB返回时设置),那么我通常会得到两个紧密间隔的事件。如果我dispatch_source_get_data()我正在监视的对象,则很容易表现出这种行为。我假设这是由于文件的mtime和atime被非原子地设置,虽然我无法验证这一点。这可能会导致向我的观察者发送虚假通知,这会增加竞争条件等的可能性。

处理此问题的最佳方法是什么?我想过为收到的最后一个事件存储一个时间戳,并且只在当前事件晚于这个时间戳一定量(几十毫秒?)时才发送通知。这听起来像是一个合理的解决方案吗?

1 个答案:

答案 0 :(得分:3)

在这种情况下,您无法逃避“竞争条件”,因为您的进程中GCD事件源的通知与其他进程对底层文件的修改不同步。所以,无论如何,你必须始终容忍你被通知的变更已经“消失”的可能性。

至于合并,请为您的应用做任何有意义的事情。有两个明显的策略。您可以立即对收到的事件采取行动,然后放弃在地板上的某个时间窗口中收到的后续事件,或者您可以延迟每个事件一段时间,在此期间您将丢弃同一文件的其他事件。它实际上只取决于什么更重要,行动迅速,或更高的静止状态(知道你永远不会确定事物是静止的。)

我要添加的唯一内容是建议您在向主线程分派任何内容之前执行所有合并。主线程具有跟踪循环等功能,这使得在某些情况下更难以获得基于时间的合并。