epoll是常用的socket通信方式,相比于select和poll来说,效率提升了不止一点半点
其一:select中socket描述符(文件描述符)集的数据结构为数组,poll的文件描述符集数据结构为链表,无论数组还是链表,它们都是线性结构,当遍历时,也只能线性遍历;而epoll文件描述符集采用的红黑树(平衡二叉树的一个变体)的数据结构,红黑树的遍历则相比于线性遍历,效率要高很多。
其二:select和poll对文件描述符集先要拷贝到内核区,内核修改后再拷贝至用户区,要经过2次拷贝;而epoll底层用的是共享内存的方式,即内核区与用户区共享一片内存,无需拷贝,也就大大提高了效率。
下面是epoll相关函数的介绍:
#include <sys/epoll.h>
// 创建一棵红黑树
int epoll_create(int size);
参数:
size: 没意义, 随便写个数就行(早期epoll数据结构为hash表,需要指定表长,但后面改为红黑树后其实树节点个数就没有什么意义了)
返回值;
>0: 文件描述符, 操作epoll树的根节点
Epoll检测的事件:
- EPOLLIN
- EPOLOUT
- EPOLLERR
// 对epoll树进行管理: 添加节点, 删除节点, 修改已有的节点属性
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
参数:
- epfd: epoll_create的返回值, 通过这个值就可以找到红黑树
- op: 要进行什么样的操作
EPOLL_CTL_ADD: 注册新节点, 添加到红黑树上
EPOLL_CTL_MOD: 修改检测的文件描述符的属性
EPOLL_CTL_DEL: 从红黑树上删除节点
- fd: 要检测的文件描述符的值
- event: 检测文件描述符的什么事件
// 检测函数
struct epoll_event events[1000];
int epoll_wait(int epfd