epoll机制
-
一、参考网址
1、epoll机制:epoll_create、epoll_ctl、epoll_wait、close
2、Linux网络编程 使用epoll实现一个高性能TCP Echo服务器
3、用C写一个web服务器(二) I/O多路复用之epoll(源码在github上)
5. 从硬件入手深入理解epoll 的本质(sunke)
6. 深入理解NIO(四)—— epoll的实现原理(sunke)
二、主要函数介绍
参考文档:Linux网络编程 使用epoll实现一个高性能TCP Echo服务器
1. epoll_create
1)函数原型
int epoll_create(int size);
2)说明
- 创建一个epoll实例,返回值是一个代表新创建的epoll实例的文件描述符
3)注意
- 参数size已被忽略,但是必须大于0
- 返回的描述符不再需要时,应该使用close()函数将它关闭
2. epoll_ctl
1)原型
#include <sys/epoll.h> typedef union epoll_data { void *ptr; int fd; uint32_t u32; uint64_t u64; } epoll_data_t; struct epoll_event { uint32_t events; /* Epoll events */ epoll_data_t data; /* User data variable */ }; int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
2)功能说明
epoll_ctl()函数用于注册socket对应的事件
3)参数说明
第一个参数:epfd是epoll实例对应的fd
第二个参数:op表示操作类型
EPOLL_CTL_ADD:注册新的fd到epfd中
EPOLL_CTL_MOD:修改已经注册的fd的监听事件
EPOLL_CTL_DEL:从epfd中删除一个fd
第三个参数:fd表示要监听的socket
第四个参数:event表示监听事件的类型,其结构体成员events可以是以下宏的集合:
EPOLLIN :表示对应的文件描述符可以读(包括对端SOCKET正常关闭);
EPOLLOUT:表示对应的文件描述符可以写;
EPOLLPRI:表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来);
EPOLLERR:表示对应的文件描述符发生错误;
EPOLLHUP:表示对应的文件描述符被挂断;
EPOLLET: 将EPOLL设为边缘触发(Edge Triggered)模式(下一节会介绍),这是相对于水平触发(Level Triggered)来说的。
EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,需要再次把这个socket加入到EPOLL队列里
3. epoll_wait
1)原型
int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
2)功能说明
等待epfd所代表的epoll实例中监听的事件发生
3)参数说明
events: 返回已准备好的事件
maxevents:最多个数,必须大于0
timeout: 指定epoll_wait函数阻塞的毫秒数的最小值,设置timeout为-1则表示永久阻塞,设置为0则会立即返回
4)返回值说明
调用成功,返回已准备好进行所要求的I/O操作的文件描述符的数量;
如果在timeout时间内没有描述符准备好,则返回0
出错时,epoll_wait()返回-1,并且把errno设置为对应的值
4. 其他说明
1)如果使用边沿触发模式,对应的socket就一定要用非阻塞模式。当epoll_wait返回可读事件后,一直使用read()函数读数据,直到read()返回EAGAIN这个错误时,表明内核收到的数据已经全部读完了。如果不使用非阻塞的话,数据读完了以后,read()函数就阻塞住了,没有办法再去处理其他的socket.