天天看点

epoll的(LT)条件触发和(ET)边缘触发

下面是二者的定义:

条件触发(LT):只要输入缓冲有数据就会一直通知该事件

边缘触发(ET):输入缓冲收到数据时仅注册1次该事件,即使输入缓冲中还留有数据,也不会再进行注册

从而我要说明的是,为什么要强调边缘触发要使用非阻塞IO;

因为在服务器端当epoll_wait监听到有客户端fd可读写时,那么就只会返回这一次,但是并不知道此fd有多少数据可读的,如果一直读到没有数据时,那么就会使得服务器端阻塞,但是条件触发会一直返回有可读数据的fd,从而就不会存在fd是返回的,且没有数据可读,从而导致进程阻塞。所以需要对边缘触发设置非阻塞IO,其实就是防止你一直读,因为你不知道这个是否是还有数据可读了。

而对于socket_fd,如果有高并发存在,此时还是边缘触发,那么当一次并没有accept所有的连接,那么下一次epoll_wait就会漏掉上一次没accept的连接。

总结一下:

1. 对于监听的 sockfd,最好使用水平触发模式,边缘触发模式会导致高并发情况下,有的客户端会连接不上。如果非要使用边缘触发,可以用 while 来循环 accept()。

2. 对于读写的 connfd,水平触发模式下,阻塞和非阻塞效果都一样,建议设置非阻塞。

3. 对于读写的 connfd,边缘触发模式下,必须使用非阻塞 IO,并要求一次性地完整读写全部数据

(参考知乎:https://www.zhihu.com/question/23614342?sort=created)

继续阅读