【问题标题】:Do we need a second thread to process time-consuming jobs with inotify?我们是否需要第二个线程来处理使用 inotify 的耗时作业?
【发布时间】:2016-05-11 13:31:27
【问题描述】:

参考: How to monitor a folder with all subfolders and files inside?

我需要监视一个目录中是否有任何扩展名为 *.log 的文件。如果创建或移入新文件,我将处理该文件。处理每个文件需要不同的时间。

问题> 我是否需要创建一个线程来监听 inotify 事件并将新文件名推送到队列中并使用另一个线程来处理队列?我担心的是,如果我不使用单独的线程,那么 inotify 可能无法跟踪由某些大文件引起的更改。

我在处理每个日志文件时使用sleep 模拟了这个问题,而没有任何多线程代码。在我看来,inotify 总是更正获取目录中所有创建/移动的文件。

这是我的模拟。

终止 1: 我运行该应用程序并在主程序中侦听 inotify 事件。每当处理一个日志文件时,我会休眠 10 秒,然后将文件名打印到控制台。

终结者 2: 我将在时间 T1 将多个文件复制到受监视的目录。 在应用程序完成处理所有以前的文件之前,我将在时间 T2 移动多个文件。 然后再次T3时间,我将在应用程序完成之前将多个文件复制到目录中。

观察: 该应用程序按我的预期处理了所有日志文件。

问题> 这是 inotify 的预期行为还是我今天早上很幸运? 也就是说,如果像上面那样模拟的话,是否会 inotify 缓存未处理的事件?

仅供参考:我使用的代码 sn-p:

#define EVENT_SIZE    ( sizeof (struct inotify_event) )
#define BUFFER_LEN  ( 1024 * ( EVENT_SIZE + NAME_MAX + 1) )

wd = inotify_add_watch( fd, root.string().c_str(), IN_CREATE | IN_MOVED_TO );

while ( true )
{
    length = read( fd, buffer, BUFFER_LEN );

    for ( int i = 0; i < length; )
    {
        const inotify_event *ptrEvent = reinterpret_cast<inotify_event *>(&buffer[i]);
        ... // processing the event
        sleep(10); // to simulate the long work
        i += INO_EVENT_SIZE + ptrEvent->len;
    }
}

【问题讨论】:

标签: c++ multithreading


【解决方案1】:

让我们做一个思想实验。显然,有某种包含事件的队列供您阅读。但是,假设您不阅读它们。如果队列的大小不受限制,您将耗尽内存,所以这是一个非首发。如果队列已绑定,您要么必须在某个时间点开始丢弃事件,要么必须执行会生成所述事件的 BLOCK 操作。后者显然是一个非首发 - 你不希望你的 fs 操作阻塞,因为带有 inotify 观察者的进程正在等待一些废话而不读取任何内容。

但最重要的是,您很可能一开始就不想使用 inotify。这里的整个业务看起来设计错误。您可能想要的是一个目录,对,它将文件重命名为。这样当文件出现时,就可以安全地读取。然后,根据具体情况,您可能只想获取 SIGUSR1 或其他东西来触发 dir 处理或通过具有确切文件名的 unix 套接字获取请求。

有问题的目录只能包含未处理的文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    • 1970-01-01
    • 2016-12-15
    • 2022-11-14
    • 2011-09-03
    相关资源
    最近更新 更多