epollLinux2.6内核新增的一个系统调用,相较于selectpoll的线性时间复杂度O(n)epoll的时间复杂度为O(1),它是Linux最高效的I/O多路复用机制。

1. epoll_create

[->bionic/libc/include/sys/epoll.h]

  1. int epoll_create(int __size);

[->bionic/libc/bionic/sys_epoll.cpp]

  1. int epoll_create(int size) {
  2. if (size <= 0) {
  3. errno = EINVAL;
  4. return -1;
  5. }
  6. return FDTRACK_CREATE(__epoll_create1(0));
  7. }

epoll_create:用于创建一个epoll实例,并返回其文件描述符,size仅仅用来检测是否大于0,并没有真正使用。如果size大于0则直接调用epoll_create1

2. epoll_create1

[->bionic/libc/include/sys/epoll.h]

  1. int epoll_create1(int __flags) __INTRODUCED_IN(21);

[->bionic/libc/bionic/sys_epoll.cpp]

  1. extern "C" int __epoll_create1(int flags);
  2. int epoll_create1(int flags) {
  3. return FDTRACK_CREATE(__epoll_create1(flags));
  4. }

epoll_create1Android 5.0开始引入,用于创建一个epoll实例,并返回其文件描述符,如果flags为0则与epoll_create效果相同,否则只能是EPOLL_CLOEXEC

3. epoll_ctl

[->bionic/libc/include/sys/epoll.h]

  1. int epoll_ctl(int __epoll_fd, int __op, int __fd, struct epoll_event* __event);

epoll_ctl:用于对epoll实例epoll_fd执行控制操作,它请求对目标文件描述符fd执行操作op操作;

epoll_fdepoll_create/epoll_create1创建的文件描述符;

[->bionic/libc/kernel/uapi/linux/eventpoll.h]

  1. #define EPOLL_CTL_ADD 1
  2. #define EPOLL_CTL_DEL 2
  3. #define EPOLL_CTL_MOD 3

op:表示op操作,分别代表添加(EPOLL_CTL_ADD)、删除(EPOLL_CTL_DEL)和修改(EPOLL_CTL_MOD)对fd的监听事件;

fd:待监听的文件描述符;

event:描述所监听的fd事件;

[->bionic/libc/include/bits/epoll_event.h]

  1. /** The union of possible data types for an `epoll_event`. */
  2. typedef union epoll_data {
  3. void* ptr;
  4. int fd;
  5. uint32_t u32;
  6. uint64_t u64;
  7. } epoll_data_t;
  8. /** The type representing an epoll() event. */
  9. struct epoll_event {
  10. uint32_t events;
  11. epoll_data_t data;
  12. }

其中epoll_data中的fd代表待监听的文件描述符;

events:描述所监听的事件,可以是以下事件类型的零个或多个组合

[->bionic/libc/kernel/uapi/linux/eventpoll.h]

  1. #define EPOLLIN (__force __poll_t) 0x00000001
  2. #define EPOLLPRI (__force __poll_t) 0x00000002
  3. #define EPOLLOUT (__force __poll_t) 0x00000004
  4. #define EPOLLERR (__force __poll_t) 0x00000008
  5. #define EPOLLHUP (__force __poll_t) 0x00000010

EPOLLIN : 表示监听的文件描述符可以读;

EPOLLOUT: 表示监听的文件描述符可以写;

EPOLLPRI: 表示监听的文件描述符有紧急的数据可读;

EPOLLERR: 表示监听的文件描述符发生错误;

EPOLLHUP: 表示监听的文件描述符被挂断;

4. epoll_wait

  1. int epoll_wait(int __epoll_fd, struct epoll_event* __events, int __event_count, int __timeout_ms);

epoll_wait:等待event_countepoll_event事件eventsepoll_fd实例中发生;

epoll_fdepoll_create/epoll_create1创建的文件描述符;

events : 分配好的epoll_event结构体数组,epoll将会把发生的事件赋值到events数组中(不可以是空指针,内核只负责把

  1. 数据复制到这个数组中,不会去帮助我们在用户态中分配内存);

maxevents : 告知内核events数组的大小;

timeout : 等待超时时间,如果函数调用成功则返回对应I/O上已准备好的文件描述符数目,返回0表示超时阻塞;