实现epoll监听只要3步骤(只需要3个API函数)
epoll (红黑树)
解决select poll的问题:
(1)每次都要传送数组和集合到内核,然后内核在返回出来
(2)每次处理事件都需要遍历处理事件
1、告诉内核一次监听那些文件描述符
内核回创建一个链表,将lfd,cfd存在链表上,在将链表的内容拷贝给用户
2、返回发生事件的文件描述符
3、epoll步骤:
一、创建树 int epoll_create(int size);
参数:大于1
返回值:树根
二、上树 epoll_ctl(int epfd,int op,int fd,struct epoll_event* event);
参数1:epfd树根
参数2:选项,上树(EP_CTL_ADD)下树(EPOLL_CTL_DEL)修改(EPOLL_CTL_MOD)
参数3:需要上树,下树,修改的文件描述符
参数4:需要上树,下树,修改的节点
红黑树上的每个节点都是一个struct epoll_event 结构体,
结构体成员有个两个,
一个是需要监听的文件描述符
一个是监听文件描述符的事件
struct epoll_event
{
uint32_t events
epoll_data_t data;
}
三、监听
epoll_wait(int epfd,struct epoll_event*events,
int maxevents,int timeout);
参数1:树根
参数2:监听到文件描述符变化后
内核返回节点复制给struct epoll_event *events 结构体数组
参数3:数组元素的大小
参数4:超时-1永久,0不等待,大于0 现实等待
1创建树
2将需要监听的文件描述符上树
3监听
4如果监听到文件描述符变化了,就返回结构体数组
epoll编写tcp高并发服务器流程
1、创建套接字
2、绑定
3、监听
4、创建树
5、上树
6、循环监听epoll_wait
7、遍历结构体数组,处理(如果lfd变化,accept提取,将提取到的连接继续上树,
如果是cfd变化,读取数据)
8、扫尾
水平触发
当epoll缓冲区有数据,就会触发epoll_wait
边沿触发
当epoll缓冲区有数据,读走了一部分,epoll_wait 就不会被触发,当有数据发送过来才触发epoll_wait函数