inotify 多次错误地通知新文件



使用 inotify 监视目录中创建的任何新文件,方法是在目录上添加监视

    fd = inotify_init();
    wd = inotify_add_watch(fd, "filename_with_path", IN_CLOSE_WRITE);
    inotify_add_watch(fd, directory_name, IN_CLOSE_WRITE);
    const int event_size = sizeof(struct inotify_event);
    const int buf_len = 1024 * (event_size + FILENAME_MAX);
    while(true) {
        char buf[buf_len];
        int no_of_events, count = 0;
        no_of_events = read(fd, buf, buf_len);
        while(count < no_of_events) {
            struct inotify_event *event = (struct inotify_event *) &buf[count];
            if (event->len) {
                if (event->mask & IN_CLOSE_WRITE) {
                    if (!(event->mask & IN_ISDIR)) {
                         //It's here multiple times 
                    }
                }
            }
            count += event_size + event->len;
        }

当我将文件搜索到目录时,这将无限循环。这段代码有什么问题?它也显示相同的事件名称和事件掩码。所以,它表明事件为相同的,无限次。

没有中断语句。如果我找到一个事件,我只需打印它并继续等待read((上的另一个事件,这应该是一个阻塞调用。相反,它开始无限循环。这意味着,读取不会阻止它,而是无限地为一个文件返回相同的值。

整个操作在单独的 boost::thread 上运行。

编辑:对不起大家。我得到的错误不是因为inotify,而是因为sqlite一开始很难检测到。我想我在这里跳枪了。经过进一步调查,我确实发现inotify运行良好。但错误实际上来自 sqlite 命令:ATTACH

该命令不是它应该的现成命令。它正在将一些元数据写入文件。所以inotify 一次又一次地收到通知。由于它们发生得如此之快,它搞砸了应用程序。我最终不得不分解代码来理解原因。

谢谢大家。

我认为你的代码没有任何问题......我运行的基本内容相同,并且工作正常。我想知道测试是否有问题,或者遗漏了代码的某些部分。如果您不介意,让我们看看是否可以消除任何歧义。

你能试试这个(我知道这几乎是一回事,但只是幽默我(并让我知道确切测试的结果吗?

1( 将以下代码放入 test.c

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sys/inotify.h>
int main (int argc, char *argv[])
{
   char target[FILENAME_MAX];
   int result;
   int fd;
   int wd;   /* watch descriptor */
   const int event_size = sizeof(struct inotify_event);
   const int buf_len = 1024 * (event_size + FILENAME_MAX);
   strcpy (target, ".");
   fd = inotify_init();
   if (fd < 0) {
      printf ("Error: %sn", strerror(errno));
      return 1;
   }
   wd = inotify_add_watch (fd, target, IN_CLOSE_WRITE);
   if (wd < 0) {
      printf ("Error: %sn", strerror(errno));
      return 1;
   }
   while (1) {
     char buff[buf_len];
     int no_of_events, count = 0;
     no_of_events = read (fd, buff, buf_len);
     while (count < no_of_events) {
       struct inotify_event *event = (struct inotify_event *)&buff[count];
       if (event->len){
         if (event->mask & IN_CLOSE_WRITE)
           if(!(event->mask & IN_ISDIR)){
              printf("%s opened for writing was closedn", target);
              fflush(stdout);
           }
       }
       count += event_size + event->len;
     }
   }
   return 0;
}

2(用gcc编译:

gcc test.c

3(在一个窗口中启动它:

./a.out

4( 在同一目录的第二个窗口中尝试:

echo "hi" > blah.txt

让我知道这是否可以正常工作,以便在每次写入文件时显示输出,并且不会像代码那样循环。如果是这样,则代码中省略了一些重要内容。如果没有,那么系统就有一些差异。

很抱歉将其放在"答案"部分,但评论太多了。

我的猜测是 read 返回 -1,并且由于您从未尝试修复错误,因此在下一次调用 Read 时会出现另一个错误,该错误也返回 -1。

最新更新