epoll是Linux2.6内核新增的一个系统调用,相较于select和poll的线性时间复杂度O(n),epoll的时间复杂度为O(1),它是Linux最高效的I/O多路复用机制。
1. epoll_create
[->bionic/libc/include/sys/epoll.h]
int epoll_create(int __size);
[->bionic/libc/bionic/sys_epoll.cpp]
int epoll_create(int size) {if (size <= 0) {errno = EINVAL;return -1;}return FDTRACK_CREATE(__epoll_create1(0));}
epoll_create:用于创建一个epoll实例,并返回其文件描述符,size仅仅用来检测是否大于0,并没有真正使用。如果size大于0则直接调用epoll_create1;
2. epoll_create1
[->bionic/libc/include/sys/epoll.h]
int epoll_create1(int __flags) __INTRODUCED_IN(21);
[->bionic/libc/bionic/sys_epoll.cpp]
extern "C" int __epoll_create1(int flags);int epoll_create1(int flags) {return FDTRACK_CREATE(__epoll_create1(flags));}
epoll_create1:Android 5.0开始引入,用于创建一个epoll实例,并返回其文件描述符,如果flags为0则与epoll_create效果相同,否则只能是EPOLL_CLOEXEC;
3. epoll_ctl
[->bionic/libc/include/sys/epoll.h]
int epoll_ctl(int __epoll_fd, int __op, int __fd, struct epoll_event* __event);
epoll_ctl:用于对epoll实例epoll_fd执行控制操作,它请求对目标文件描述符fd执行操作op操作;
epoll_fd:epoll_create/epoll_create1创建的文件描述符;
[->bionic/libc/kernel/uapi/linux/eventpoll.h]
#define EPOLL_CTL_ADD 1#define EPOLL_CTL_DEL 2#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]
/** The union of possible data types for an `epoll_event`. */typedef union epoll_data {void* ptr;int fd;uint32_t u32;uint64_t u64;} epoll_data_t;/** The type representing an epoll() event. */struct epoll_event {uint32_t events;epoll_data_t data;}
其中epoll_data中的fd代表待监听的文件描述符;
events:描述所监听的事件,可以是以下事件类型的零个或多个组合
[->bionic/libc/kernel/uapi/linux/eventpoll.h]
#define EPOLLIN (__force __poll_t) 0x00000001#define EPOLLPRI (__force __poll_t) 0x00000002#define EPOLLOUT (__force __poll_t) 0x00000004#define EPOLLERR (__force __poll_t) 0x00000008#define EPOLLHUP (__force __poll_t) 0x00000010
EPOLLIN : 表示监听的文件描述符可以读;
EPOLLOUT: 表示监听的文件描述符可以写;
EPOLLPRI: 表示监听的文件描述符有紧急的数据可读;
EPOLLERR: 表示监听的文件描述符发生错误;
EPOLLHUP: 表示监听的文件描述符被挂断;
4. epoll_wait
int epoll_wait(int __epoll_fd, struct epoll_event* __events, int __event_count, int __timeout_ms);
epoll_wait:等待event_count个epoll_event事件events从epoll_fd实例中发生;
epoll_fd :epoll_create/epoll_create1创建的文件描述符;
events : 分配好的epoll_event结构体数组,epoll将会把发生的事件赋值到events数组中(不可以是空指针,内核只负责把
数据复制到这个数组中,不会去帮助我们在用户态中分配内存);
maxevents : 告知内核events数组的大小;
timeout : 等待超时时间,如果函数调用成功则返回对应I/O上已准备好的文件描述符数目,返回0表示超时阻塞;
