开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第7天,点击查看活动详情
epoll 的三个函数
int epoll_create(int size);
-
size: epoll管理的文件描述符的数量(Linux 2.6.8 对 size 没有限制,可以随意,但是 size 必须大于 0)
-
返回值: 返回一个 epoll 文件描述符,这个 epoll 文件描述符也可以被其他文件描述符所监听管理
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
-
epfd: 用于控制某个 epoll 文件描述符事件;
-
op: 控制 epoll 文件描述符事件;op 可以为
- EPOLL_CTL_ADD: 往 epoll 文件描述符中注册 fd , 利用
- EPOLL_CTL_MOD: 修改 fd 注册在 epoll 上面的事件
- EPOLL_CTL_DEL: 把注册的 fd 从epoll 中 删除
-
fd: 要注册在 epoll 上的文件描述符
-
*event: 事件指针:
event 相关结构体如下所示:
```
struct epoll_event {
uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};
// 联合体,同一时刻,*ptr,fd u32, u64 仅有一个有效
typedef union epoll_data {
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;
```
结构体 epoll_event 中的 events 可选项如下:
-
EPOLLIN: fd 可读
-
EPOLLOUT: fd 可写
-
EPOLLRDHUP: 对端关闭了连接,或者关闭写端
-
EPOLLPRI: 带外数据
-
EPOLLERR: 错误
-
EPOLLHUP: 文件描述符被挂断
-
EPOLLET: 边缘触发;对于读事件 EPOLLIN,只有socket上的数据从无到有,EPOLLIN 才会触发;对于写事件 EPOLLOUT,只有在socket写缓冲区从不可写变为可写,EPOLLOUT 才会触发(刚刚添加事件完成调用epoll_wait时或者缓冲区从满到不满)
-
EPOLLLT:水平触发;对于读事件 EPOLLIN,只要socket上有未读完的数据,EPOLLIN 就会一直触发;对于写事件 EPOLLOUT,只要socket可写(一说指的是 TCP 窗口一直不饱和,我觉得是TCP缓冲区未满时,这一点还需验证),EPOLLOUT 就会一直触发。
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
-
epfd: 要检测的 epoll 文件描述符
-
event: 用于回传待处理事件的数组
-
maxevents: 告诉内核 events 数组的大小
-
timeout: 超时事件
- -1: 永久阻塞
- 0: 立即返回
- >0: 等待timeout事件后立即返回