是否可以使用`select()`轮询kqueue的文件描述符?

时间:2015-06-18 13:29:56

标签: macos select freebsd kqueue

使用kqueue()创建kqueue时,会返回文件描述符。但似乎无法使用select()对此文件描述符进行有意义的轮询。我理解标准kqueue()轮询/读取的方式是kevent(...),但我正在尝试与使用{{1}轮询文件描述符的一些遗留代码集成}}

此处的目标是能够触发可由此基于select()的轮询机制检测到的“用户事件”(即使事件最终需要使用select“消耗”后来)。这看起来就像kevent()生成的那样,但是一个快速的实验表明EVFILT_USER没有报告kqueue的fd在添加(和触发)事件时准备好读取kqueue,它只是超时(或永远阻止)。 (但是等效的select()调用查看/返回事件。)

我做错了吗?或者用kevent()

来轮询kqueue的fd是不可能的

1 个答案:

答案 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