一、epoll的工作原理
epoll相比select和poll的优势:
1. 每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大;而epoll保证了每个fd在整个过程中只会拷贝一次。
2. 每次调用select都需要在内核遍历传递进来的所有fd;而epoll只需要轮询一次fd集合,同时查看就绪链表中有没有就绪的fd就可以了。
3. 内核仅会将有 IO 事件的文件描述符返回给用户,用户也无需遍历整个文件描述符集合。
4. 没有文件描述符1024的限制(poll和epoll都是)
二、epoll的API
1、创建EPOLL句柄
2、向EPOLL对象中添加、修改或者删除感兴趣的事件
举例:将cfd文件描述符上树
int epfd = epoll_create(1);// 创建EPOLL句柄
// 结点的结构体
struct epoll_event ev;
ev.data.fd = cfd;
ev.events = EPOLLIN;
/****************************************
* events取值:
* EPOLLIN 表示有数据可以读出(接受连接、关闭连接)
* EPOLLOUT 表示连接可以写入数据发送(向服务器发起连接,连接成功事件)
* EPOLLERR 表示对应的连接发生错误
* EPOLLHUP 表示对应的连接被挂起
*****************************************/
// 结点上树
epoll_ctl(epfd,EPOLL_CTL_ADD,cfd,&ev);
3.收集在EPOLL监控的事件中已经发生的事件
三、epoll的工作方式
Level_triggered(水平触发) :只要这个fd还有数据可读,每次 epoll_wait都会返回它的事件,提醒用户程序去操作;
Edge_triggered(边缘触发):它只会提示一次,直到下次再有数据流入之前都不会再提示了,无论fd中是否还有数据可读。
边沿触发设置方式:ev.events = EPOLLIN | EPOLLET