epoll 误区

来源:互联网 发布:js修改input disabled 编辑:程序博客网 时间:2024/06/10 00:13

http://my.oschina.net/u/732357/blog/78122

对于epoll的网上一大抄的太多,而其中对ET模式的描述基本都是不准确的

以下是被抄袭最多的部分,而对于ET的误区就在这里

EPOLL事件分发系统可以运转在两种模式下:Edge Triggered (ET)、Level Triggered (LT)。
LT是缺省的工作方式,并且同时支持block和no-block socket;在这种做法中,内核告诉你一个文件描述符是否就绪了,然后你可以对这个就绪的fd进行IO操作。如果你不作任何操作,内核还是会继续通知你 的,所以,这种模式编程出错误可能性要小一点。传统的select/poll都是这种模型的代表。

ET是高速工作方式,只支持no-block socket。在这种模式下,当描述符从未就绪变为就绪时,内核通过epoll告诉你。然后它会假设你知道文件描述符已经就绪,并且不会再为那个文件描述 符发送更多的就绪通知,直到你做了某些操作导致那个文件描述符不再为就绪状态了。但是请注意,如果一直不对这个fd作IO操作(从而导致它再次变成未就 绪),内核不会发送更多的通知。

按照以上描述ET模式下,比如EPOLLIN事件到达,如果你不recv直到返回错误,那么之后有数据到达,系统不会再通知你。但事实上并不是这样,某些时候系统还是会通知你的,下面对Epoll事件触发时机做个总结

EPOLLIN

ET模式:

    每次EPOLL_CTL_ADD或EPOLL_CTL_MOD时,如果加入前,就是可读状态,那么加入后会触发1次 
    不管sock缓冲是否读完,只要对方有send或connect或cloase或强退,就会触发EPOLLIN 

LT模式:只要socket可读,就会一直触发EPOLLIN 

EPOLLOUT 
ET模式: 
    每次EPOLL_CTL_ADD或EPOLL_CTL_MOD时,如果加入前,就是可写状态,那么加入后会触发1次 
    如果EPOLLOUT与EPOLLIN一起注册,不管sock发送缓冲是否从满变不满,只要socket发送是不满的,那么每次EPOLLIN触发时,都会触发EPOLLOUT 

LT模式:只要socket可写,就会一直触发EPOLLOUT 


简单来说,ET模式下,只要监听了EPOLLIN和EPOLLOUT,socket的每次动作(包括close与不close直接强退),都会触发1次, 与读写缓冲的状态无关。 


EPOLLHUP 
    每次有未连接的socket被加入监听列队时,会触发EPOLLHUP 
    比如socket创建了套接字以后未调用connect或未调用listen,就直接加入epoll监听列队 
    或者close了以后再加入epoll监听列队 
0 0
原创粉丝点击