【问题标题】:Is it possible to poll a kqueue's file descriptor with `select()`?是否可以使用 `select()` 轮询 kqueue 的文件描述符?
【发布时间】:2015-06-18 13:29:55
【问题描述】:

当你使用kqueue() 创建一个 kqueue 时,你会得到一个文件描述符。但似乎无法使用select() 有意义地轮询此文件描述符。我知道从kqueue() 轮询/读取的标准方法是使用kevent(...),但我正在尝试与一些使用select() 轮询文件描述符的遗留代码集成。

这里的目标是能够触发可以通过这种基于select 的轮询机制检测到的“用户事件”(即使该事件最终需要稍后使用kevent() 来“使用”)。这看起来像是 EVFILT_USER 天生要做的事情,但是一个快速实验表明 select() 不会在 kqueue 中添加(和触发)事件时报告 kqueue 的 fd 已准备好读取,它只是超时(或永远阻塞)。 (但等效的kevent() 调用确实看到/返回事件。)

我做错了吗?还是无法使用 select() 轮询 kqueue 的 fd?

【问题讨论】:

    标签: macos select freebsd kqueue


    【解决方案1】:

    The paper,描述 kqueue/kevent 说(第 6.5 节):

    由于一个普通的文件描述符引用了kqueue,它可以取 参与通常可以对描述符执行的任何操作。 应用程序可以 select()、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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-27
      • 1970-01-01
      相关资源
      最近更新 更多