使用kqueue()
创建kqueue时,会返回文件描述符。但似乎无法使用select()
对此文件描述符进行有意义的轮询。我理解标准从kqueue()
轮询/读取的方式是kevent(...)
,但我正在尝试与使用{{1}轮询文件描述符的一些遗留代码集成}}
此处的目标是能够触发可由此基于select()
的轮询机制检测到的“用户事件”(即使事件最终需要使用select
“消耗”后来)。这看起来就像kevent()
生成的那样,但是一个快速的实验表明EVFILT_USER
没有报告kqueue的fd在添加(和触发)事件时准备好读取kqueue,它只是超时(或永远阻止)。 (但是等效的select()
调用会查看/返回事件。)
我做错了吗?或者用kevent()
答案 0 :(得分:3)
The paper,描述kqueue / kevent说(第6.5节):
由于普通文件描述符引用了kqueue,因此可以使用 参与任何通常可以在描述符上形成的操作。 应用程序可以选择(),poll(),close(),甚至创建kevent 引用kqueue;
对于FreeBSD来说确实如此,我已经用以下代码检查了这个:
struct kevent e;
fd_set fdset;
int kq=kqueue();
EV_SET(&e, 1, EVFILT_USER, EV_ADD, 0, 0, NULL);
kevent(kq, &e, 1, 0, 0, 0); // register USER event filter
EV_SET(&e, 1, EVFILT_USER, EV_ADD, NOTE_TRIGGER, 0, NULL);
kevent(kq, &e, 1, 0, 0, 0); // trigger USER event
FD_ZERO(&fdset);
FD_SET(kq,&fdset);
select(FD_SETSIZE,&fdset, 0, 0, 0); // wait for activity on kq
int res = kevent(kq, 0, 0, &e, 1, 0); // get the event