FreeBSD 下的 kqueue 监听的单位是 (ident, filter) , Linux 下的 epoll 监听的单位是单个 fd 。在 Linux 下,通常你需要对 epoll 监听的 fd 做一些额外的记录工作,以便下次更改时查询。这里直接用 Redis 的代码做个示例。
1 | // FreeBSD kqueue |
从上面的代码可以看到,FreeBSD kqueue 在改变 fd 的监听事件时不需要做额外的记录工作。
1 | // Linux epoll |
从上面的代码可以看到,Linux epoll 在改变 fd 的监听事件时需要查询之前监听的事件,记录当前监听的事件。
这样 API 的调用者就无需做额外的记录工作,但读写事件需要额外的同步机制去保证线程安全。
Q3 Is the epoll file descriptor itself poll/epoll/selectable?
A3 Yes. If an epoll file descriptor has events waiting, then it will indicate as being readable.
---- epoll(7)
下面的代码利用了 epoll fd 本身在有等待事件时是可读的特性,展示了一种新的在 Linux epoll 下对 fd 读写
事件进行监听的方法。该方法分离了 fd 的读和写,这样我们就可以把 fd 的读和写交给不同的线程去处理。
1 | // initialization |
1 | // wait read event |
1 | // wait write event |
1 | // polling |
现在,我们有了一个 kqueue 式的 epoll 接口。 Enjoy it!