epoll
epoll_create
用于创建一个epoll实例,并返回一个这个实例的文件描述符
epoll_ctl
通过该函数标记对特定的问价描述符感兴趣,当前在epoll实例上注册的文件描述符集有时称为epoll集。
epoll_wait
等待IO事件,如果当前没有可用事件,则会阻塞
edge-triggered
Netty使用ET。
应用程序必须立即处理该事件
ET会在read或write在返回EAGAIN(对于网络IO来说也可能是EWOULDBLOCK, 表示被标记为非阻塞的操作会发生阻塞的异常)时才会返回消息。
level-triggered
JDK使用LT。
应用程序可以不立即处理该事件
LT在读完部分byte后返回,并且如果还有未读的btye,则会立即发起下一个事件,但是如果连接关闭,需要将Selector移除,并创建一个新的Selector,否则会导致无限的read事件。
BUG原因:在部分Linux的2.6的kernel中,poll和epoll对于突然中断的连接socket会对返回的eventSet事件集合置为POLLHUP,也可能是POLLERR,eventSet事件集合发生了变化,这就可能导致Selector会被唤醒。
Netty: 会判断等待时长,如果有512次空轮询,则会重新创建Selector
综上
ET模式在很大程度上减少了epoll事件被重复触发的次数,因此效率要比LT模式高。epoll工作在ET模式的时候,必须使用非阻塞套接口,以避免由于一个文件句柄的阻塞读/阻塞写操作把处理多个文件描述符的任务饿死。