为啥不通知更新?
Posted
技术标签:
【中文标题】为啥不通知更新?【英文标题】:Why doesn't inotify update?为什么不通知更新? 【发布时间】:2011-10-20 01:46:26 【问题描述】:我正在用 C 语言为 Minecraft 服务器编写一个 inotify 观察程序。基本上,它监视 server.log,获取最新行,解析它,以及它是否匹配正则表达式;执行一些操作。
程序通过“匹配正则表达式>> server.log的回显字符串”正常工作,它解析并执行它应该做的事情。但是,当字符串通过 Minecraft 服务器自动写入文件时,在我关闭服务器或(有时)注销之前它不起作用。
我会发布代码,但我想知道它是否与 ext4 将数据刷新到磁盘或类似的东西无关;文件系统问题。但如果是这样的话会很奇怪,因为“tail -f server.log”会在文件更新时更新。
【问题讨论】:
服务器是否真的在每次写入时将内容刷新到磁盘?你能做些什么来强迫它这样做吗? 我当然希望如此。如果没有人立即知道问题所在,我一定会查看源代码。 【参考方案1】:解决了我自己的问题。事实证明,服务器写入日志文件的速度比观察者读取的速度要快;所以观察者失去了同步。
我通过在它处理“如果当前日志文件中的行数超过日志的记录长度,重新处理文件直到两者相等”的事件后添加一个检查来修复它。
感谢您的帮助!
【讨论】:
【参考方案2】:大概是因为您正在监视IN_CLOSE
事件,直到服务器关闭(并关闭日志文件句柄)才可能发生。有关inotify_add_watch()
调用的有效掩码参数,请参阅man inotify(7)。我希望你会想要使用IN_WRITE
。
【讨论】:
其实我用的是IN_MODIFY
。我稍后会检查IN_WRITE
。谢谢!
没有名为IN_WRITE
的掩码。 IN_MODIFY
似乎与您所描述的最接近,这又回到了我原来的问题。【参考方案3】:
您的理论很可能是正确的,日志文件正在被操作系统缓冲,并且日志写入器没有刷新该缓冲区,因此所有内容都将保留在缓冲区中,直到文件关闭或缓冲区已满。一种快速的测试方法是将日志启动到您知道它会将事件写入日志的位置,然后强制关闭它以使其无法关闭句柄,如果日志为空则绝对是缓冲区。如果您可以获取文件句柄/描述符,则可以使用setbuf
来移除缓冲,但会以性能为代价。
【讨论】:
感谢您的建议,我今天晚些时候一定会试试这个!当您说使用setbuf
时,您是说尝试将文件描述符从正在运行的Java 进程(可能通过在启动时将其写入文件)传输到C 观察程序,然后从中使用setbuf
?这两种不同的语言在这方面是否兼容?
@screennameless: 底层操作系统文件描述符是相同的,所以如果你能得到已经打开的句柄,你就可以删除缓冲,虽然我不太确定如何在 linux 下做到这一点:|
谢谢,我一定要试试这个!我认为传递描述符的最简单方法是在打开文件时将其写入文件。我稍后会尝试实现它。以上是关于为啥不通知更新?的主要内容,如果未能解决你的问题,请参考以下文章