zoukankan      html  css  js  c++  java
  • epoll的LT和ET(转)

    1 socket IO事件

    1.1 读事件

    读事件:句柄从不可读变成可读,或者句柄写缓冲区有新的数据进来且超过SO_RCVLOWAT。
    常见的产生读事件有如下几种:

    • socket有一个未清除的错误。如非阻塞的connect连接错误会使socket变成可读写状态。
    • 非阻塞accept有新的连接进来。
    • socket写对端关闭,read返回0。
    • socket读缓冲区有新的数据进来且超过SO_RCVLOWAT

    1.2 写事件

    写事件:句柄从不可写变成可写,或者句柄写缓冲区有新的数据进来而且缓冲区水位高于SO_SNDLOWAT。常见的写事件事件有如下几种:

    • socket有一个未清除的错误。例如非阻塞connect连接出错会导致socket变成可读可写状态。
    • 非阻塞connect连接成功后端口状态会变成可写。
    • socket读对端关闭,socket变成可写状态,产生SIGPIPE信号。
    • socket写缓冲区有新的数据进来且超过SO_SNDLOWAT
      在epoll中,读事件对应EPOLLIN,写事件对应EPOLLOUT。

    2 ET

    句柄在发生读写事件时只会通知用户一次
    ET模式主要关注fd从不可用到可用或者可用到不可用的情况。
    ET只支持非阻塞模式。

    2.1 应用层逻辑

    ET模式下读写操作要时用wihle循环,直到读/写够足够多的数据,或者读/写到返回EAGAIN。尤其时在写大块数据时,一次write操作不足以写完全部数据,或者在读大块数据时,应用层缓冲区数据太小,一次read操作不足以读完全部数据,应用层要么一直调用while循环一直IO到EGAIN,或者自己调用epoll_ctl手动触发ET响应。

    2.2 优缺点

    缺点:应用层业务逻辑复杂,容易遗漏事件,很难用好。
    优点:相对LT模式效率比较高。

    3 LT

    只要句柄一直处于可用状态,就会一直通知用户。
    LT模式下,句柄读缓冲区被读空后,句柄会从可用转变未不可以用,这个时候不会通知用户。写缓冲区只要还没写满,就会一直通知用户。
    LT模式支持阻塞和非阻塞两种方式。epoll默认的模式是LT。
    LT下,应用层的业务逻辑比较简单,更不容易遗漏事件,更不容易出错。通常,在将数据写完后,我们会关闭句柄的写事件。

    3.1 优缺点

    优点:编程更符合用户直觉,业务层逻辑更简单。
    缺点:效率比ET低。

    3.2 ET比LT更高效得原因

    ET在通知用户后,就会把fd从就绪队列里删除。而LT通知用户后fd还在就绪链表中,随着fd的增多,就绪链表越大。下次epoll要通知用户时还需要遍历整个就绪链表。遍历的性能是线性,如果fd的数量非常多,就会带来比较显著的效率下降。
    同样数量的fd下,LT模式维护的就绪链表比ET的大。

    3.3 非阻塞模式下的accept该用什么触发模式?

    LT和ET各有优缺点。使用哪种模式取决于并发量。当并发量比较小时,比较推荐LT,因为LT模式下应用的读写逻辑比较简单,不容易遗漏事件,代码不易出错好维护,而且性能损失不大。当并发量非常大时,推荐使用ET模式,可以有效提升EPOLL效率。

    3.4 LT模式下,可写状态的fd会一直触发事件,该怎么处理这个问题

    • 方法1:每次要写数据时,将fd绑定EPOLLOUT事件,写完后将fd同EPOLLOUT从epoll中移除。
    • 方法2:方法一中每次写数据都要操作epoll。如果数据量很少,socket很容易将数据发送出去。可以考虑改成:数据量很少时直接send,数据量很多时在采用方法1.

    应用

    使用ET的例子

    nginx

    使用LT的例子

    redis

  • 相关阅读:
    台州 OJ 3847 Mowing the Lawn 线性DP 单调队列
    洛谷 OJ P1417 烹调方案 01背包
    快速幂取模
    台州 OJ 2649 More is better 并查集
    UVa 1640
    UVa 11971
    UVa 10900
    UVa 11346
    UVa 10288
    UVa 1639
  • 原文地址:https://www.cnblogs.com/wangbin/p/10468436.html
Copyright © 2011-2022 走看看