【问题标题】:read on inotify descriptor is blocked forever读取 inotify 描述符被永久阻塞
【发布时间】:2022-03-08 15:27:23
【问题描述】:

我的程序使用inotify 来监控文件的更改。 我的代码如下:

    fd = inotify_init();
    wd = inotify_add_watch(fd, "./test.txt", IN_ALL_EVENTS);
    len = read(fd, buff, BUFF_SIZE);
    while (i < len) {
        struct inotify_event *pevent = (struct inotify_event *) &buff[i];
                //process events
        i += sizeof(struct inotify_event) + pevent->len;
    }

但是,在我收到了几个事件以在受监控文件中进行第一次更改(事件IN_OPEN、IN_MODIFY、IN_ACESS 等)之后,受监控文件中的后续更改确实会生成任何其他事件 ==>我的程序挂在读取函数(读取被阻止)

你们能帮我解释一下这个错误吗?

【问题讨论】:

    标签: c++ c inotify file-monitoring


    【解决方案1】:

    请显示“./test.txt”实际发生的操作以及有关您的代码的更多信息(buff,BUFF_SIZE)。您需要检查以下几点:

    • 有一些特殊事件,如 IN_IGNORED,可能会从文件中删除监视
    • 我建议使用 select/poll/epoll 来监控 fd 而不是 BLOCKING 读取它。

    【讨论】:

    • 感谢您的回答。它对我有很大帮助。我只是想问你另一个问题。为什么当我使用 Vim 或 Gedit 打开文件时,总是收到事件 IN_DELETE_ITSELF?
    • @khanhhh89 我相信你已经编辑了“test.txt”并保存了它。我的 vim 是 7.3,我发现它实际上使用 open("test.txt", O_WRONLY|O_CREAT|O_TRUNC, 0664) 并向其写入内容。所以我认为 IN_DELETE_ITSELF 是由 O_TRUNC 引起的。
    • @wgwang 所以这就是为什么在我阅读第一个事件后,再次使用 inotify_add_watch("test.txt") 会导致错误“没有这样的文件或目录”???
    • test.txt 上实际发生了哪些操作?我尝试打开 vim 的inotify,保存但没有IN_DELETE_ITSELF 或IN_IGNORED
    • @khanhhh89 我尝试了另一个版本:vim 7.0,是的,我得到了你的结果。实际上,当你编辑test.txt时,vim 7.0会先rename("test.txt", "test.txt~"),然后将你的编辑内容写入test.txt,最后写入unlink("test.txt~")。所以你看到原来的test.txt实际上被删除了,inotify得到IN_DELETE_ITSELF or IN_IGNORED的事件。对于 vim 7.3,这不会发生。
    【解决方案2】:

    使用 fcntl 使文件描述符非阻塞。

    【讨论】:

      猜你喜欢
      • 2011-08-02
      • 1970-01-01
      • 1970-01-01
      • 2015-05-31
      • 1970-01-01
      • 1970-01-01
      • 2021-06-19
      • 2019-11-17
      • 2018-05-15
      相关资源
      最近更新 更多