如何在锁定“ kevent”的同时向“ kqueue”添加“ kevent”?

问题描述

让我们假设kqueue正在监听文件修改

(注意:为方便起见,删除错误管理)

#include <sys/types.h>
#include <sys/event.h>
#include <signal.h>
#include <cstdlib>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <vector>
#include <array>
#include <fstream>

using namespace std;

auto main() ->int
{
    constexpr static int keventsMode = NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_LINK | NOTE_RENAME | NOTE_REVOKE;

    // Create the queue
    auto kernelQueue = kqueue();

    // Open the file descriptor to be monitored
    auto file = open("./test.txt",O_EVTONLY);

    // Create the structures of kevents to monitor
    std::vector<struct kevent> keventsToMonitor;
    keventsToMonitor.emplace_back();
    EV_SET( &(*keventsToMonitor.rbegin()),file,EVFILT_VNODE,EV_ADD | EV_CLEAR,keventsMode,nullptr);

    // Create a structure to get events
    std::array<struct kevent,10> keventsData;

    // Event loop
    while( true )
    {
        // Blocking function!!! HOW TO UNBLOCK? 
        auto eventCount = kevent(kernelQueue,keventsToMonitor.data(),keventsToMonitor.size(),keventsData.data(),keventsData.size(),nullptr/*&timeout*/);
        // .. manage events here
        if (eventCount) cout << "Some events" << endl;
        else cout << "timeout" << endl;
    }
}

假设我们在线程中移动while循环,并且想向kqueue添加一个附加文件

问题在于kevent()函数将一直阻塞,直到新事件到达为止,因此,添加文件直到kevent()取消阻塞并且对{{1}中的新条目执行新调用之后,文件才能生效}。

如何避免这种情况?

  1. 使用超时:如果我们使用较长的超时时间(例如10秒),则添加文件将花费太长时间;如果我们使用较短的超时时间(例如50毫秒),则cpu使用效率将降低。

  2. 信号keventsToMonitor,但如何?

可以创建一个“侦听”文件,并对其进行修改以解除对kevent函数的阻止,但是很遗憾,我希望有一个更简单的解决方案。

如何取消阻止kevent(),以便可以将新文件添加到列表中进行监视?还是有其他解决方案可以有效地添加要监视的新文件

理想的解决方案是:

kevent()

解决方法

创建一个管道,用EV_READ在kqueue中添加reading fd。在另一个线程中写入管道会导致 kevent() 返回。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...