问题描述
#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}中的新条目执行新调用之后,文件才能生效}。
如何避免这种情况?
可以创建一个“侦听”文件,并对其进行修改以解除对kevent
函数的阻止,但是很遗憾,我希望有一个更简单的解决方案。
如何取消阻止kevent()
,以便可以将新文件添加到列表中进行监视?还是有其他解决方案可以有效地添加要监视的新文件?
理想的解决方案是:
kevent()
解决方法
创建一个管道,用EV_READ在kqueue中添加reading fd。在另一个线程中写入管道会导致 kevent() 返回。