epoll 事件处理的细节分析2
准确的说epoll事件就是IO事件,包括文件、socket、pipe等,linux把他们统称为文件,统一的接口调用,驱动层不同实现。
这里分成四类:
监听套餐接字,链接套接字,文件,pipe,相应的触发条件
1.监听套接字:
有新链接连上临听套接字,并三次握手成功时
2.链接套接字
有IO读写,且传输层接收/发送完毕
3.普通文件
有IO读写
4.pipe
有IO读写,且有锁保护。
虽然有统一接口,但还是有区分的,先看epoll 源码:
if (epi->event.events & EPOLLONESHOT)
epi->event.events &= EP_PRIVATE_BITS;
else if (!(epi->event.events & EPOLLET)) {
list_add_tail(&epi->rdllink, &ep->rdllist);
}
可以看到 当事件类型不是 EPOLLET时,会反复触发。
因此对于以上四种类型,1,3,4应该不加 EPOLLET,而第2种一定要加上 EPOLLET,否则当一个链接由客
户端挂掉的时候,服务器会不停的收到事件。
ET/LT实际上是电力上的概念,有两种电路,一种里面有高电阻,另外一个是有电容。
第一种情况,只有电压达到一定的值的情况下才能导通,称为水平触发 eage triggered。
第二种情况,只有电压发生变化的情况下才能导通, 称为边沿触发,level triggered。
epoll 按照这个意思,对于LT,当有事件时,当有IO时就会一直触 发,直到IO被完全传送。
对于ET,有IO时触发一次,IO消失时触发一次,即上升沿下降沿。
这样如果对监听链接用ET的话,可能就会丢掉很多链接,而如对普通链接用LT的话就会做无用功。
这样是不是更形象了?