为啥需要使用 inotify_add_watch() 调用 read() 两次

Posted

技术标签:

【中文标题】为啥需要使用 inotify_add_watch() 调用 read() 两次【英文标题】:Why is it required to call read() twice with inotify_add_watch()为什么需要使用 inotify_add_watch() 调用 read() 两次 【发布时间】:2018-08-17 20:45:34 【问题描述】:

我正在尝试在文件被修改时使用 inotify_add-watch() 获取通知 (inotify_add_watch (fd, filename.c_str(), IN_MODIFY);) 在 linux 文件系统上(linux 内核 4.9.0)。

但在收到通知后,预计 read() 会调用两次,直到我收到有关文件 /etc/temp 的下一次修改的通知。有人可以澄清为什么我需要两次调用 read() 吗?谢谢。

int fd, wd;
fd = inotify_init ();

if (fd < 0)

    perror ("inotify_init () = ");

else

    std::string filename = "/etc/test";
    wd = inotify_add_watch (fd, filename.c_str(), IN_MODIFY);

    if (wd < 0)
    
    perror ("inotify_add_watch");
    
    else
    
        char* buffer = new char[1024];
        while(true)
        
            //first read blocks until the /etc/temp file is modified, 
            //it returns 16 which is sizeof(struct inotify_event)
            printf("first read %d), read( fd, buffer, 1024));

            //second read() does not block and read returns 16 again
            printf("second read %d), read( fd, buffer, 1024));
         
     

【问题讨论】:

【参考方案1】:

您必须在它再次开始阻塞之前消耗所有待处理的事件。

当你例如做echo foo &gt; /etc/test,你可能会得到两个事件:一个用于截断,一个用于写入。

如果两个都不吃,下一个会立即返回。

【讨论】:

以上是关于为啥需要使用 inotify_add_watch() 调用 read() 两次的主要内容,如果未能解决你的问题,请参考以下文章

inotify_add_watch 失败,没有这样的文件或目录

inotify_add_watch 是不是按升序返回监视描述符?

推送到 bitbucket 时出现错误“inotify_add_watch”

Docker 守护进程无法启动:inotify_add_watch: no such file or directory

inotify_add_watch 相对于 O_PATH dirfd

inotify_add_watch 在 /sys/class/net/eth0/operstate 上失败