Function epoll

Source
pub fn epoll()
Expand description

§epoll

                        +--------------------------------+     +-------------------------+
                        | epoll_ctl                      |     | epoll_wait              |
                        |                                |     |                         |
                        |                                |     |         +----+          |
                        |                 +---+          |     |         |    |          |
                        |                 |   |          |     |         |    |          |
                        |               +-+---+--+       |     |         +--+-+          |
                        |               |        |       |     |            |            |
                        |            +--++     +-++      |     |            |            |
epoll_create  +---->    |            |   |     |  |      |     |         +--+-+          |
                        |            +-+-+     +--+      +---->+         |    |          |
                        |              |                 |event|         |    |          |
                        |         +----+--+              |     |         +--+-+          |
                        |         |       |              |     |            |            |
                        |         ++      |              |     |            |            |
                        |        +--+   +-+-+            |     |         +--+-+          |
                        |        |  |   |   |            |     |         |    |          |
                        |        +--+   +---+            |     |         |    |          |
                        |                                |     |         +----+          |
                        |                    红 黑 树     |     |                 链 表    |
                        +--------------------------------+     +-------------------------+

  • epoll_create(int size) : 内核产生一个epoll实例数据结构,并返回一个epfd
  • epoll_ctl(int epfd, int op, int fd, struct epoll_event *event):将被监听的描述符添加到红黑树或从红黑树中删除或者对监听事件进行修改。
  • epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout): 阻塞等待注册的事件发生,返回事件的数目,并将触发的事件写入events数组中

epoll 两种触发机制:

  • 水平触发机制(LT)。缓冲区只要有数据就触发读写。epoll 默认工作方式。select/poll只支持该方式。
  • 边缘触发机制(ET)。缓冲区空或满的状态才触发读写。nginx 使用该方式,避免频繁读写。

惊群问题:

当多个进程/线程调用epoll_wait时会阻塞等待,当内核触发可读写事件,所有进程/线程都会进行响应,但是实际上只有一个进程/线程真实处理这些事件。 Liux 4.5 通过引入 EPOLLEXCLUSIVE 标识来保证一个事件发生时候只有一个线程会被唤醒,以避免多侦听下的惊群问题。