Mac OS X上的kqueues:奇怪的事件顺序

时间:2011-11-28 08:21:24

标签: macos vim bsd kqueue hfs

我使用kqueues / kevent(2)监视文件中单独线程的更改。 (我监控Python文件以进行重新分析)

我订阅如下:

EV_SET(&file_change, pyFileP, EVFILT_VNODE,
       EV_ADD | EV_CLEAR,
       NOTE_DELETE |  NOTE_WRITE | NOTE_EXTEND | 
               NOTE_ATTRIB | NOTE_LINK | NOTE_RENAME | NOTE_REVOKE,
       0, 0);

当我使用Vim写入文件“/tmp/somefile.py”时,我得到两个单独的kevents: 这些事件的标志(event.fflags)是:

NOTE_RENAME

NOTE_DELETE | NOTE_LINK

我从未收到“NOTE_WRITE”活动! 这似乎与Vim写这些文件的方式有关,因为如果我这样做

echo "sometext" >> /tmp/somefile.py

我确实得到了:

NOTE_WRITE|NOTE_EXTEND

事件。

奇怪,是吗?我没有检查过Vim源代码,但它必须做一些奇怪的事情,还是仅仅使用以这种方式实现的用户级函数?

我真的没想到这个。这是一个已知问题,我只需要检查所有可能的事件,或者是否有一个已知的接口可以真正检查文件是否已被写入?

1 个答案:

答案 0 :(得分:1)

实际上发生的事情是Vim不会首先写入同一个文件 它可能会将其重命名为其他内容,然后创建另一个文件(链接)。 您可以通过执行以下操作来确认:

$ vim file -c wq

这将打开一个文件并写入。现在检查inode:

$ ls -i
30621217 file

再次使用Vim编写文件并重新检查inode:

$ vim file -c wq
$ ls -i
30621226 file

这是完全不同的。这意味着第二个文件实际上是另一个文件 (链接到另一个inode)具有相同的名称,旧的未链接。

许多编辑都这样做。我无法确认为什么Vim采用这种方法。 可能以确保安全:如果您首先重命名该文件并出现问题 在编写新文件时,您仍然使用旧文件。如果你开始写作 在一个文件和一个问题发生(即使有内存)你可能会失去一部分 它的。的也许