• 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

  • 相关阅读:
    Cassandra内部架构
    Cassandra数据模型
    windows10 docker安装使用
    vue用async、await实现同步请求
    navicat mysql 书写存储过程并导出成sql
    idea svn 文件还原到指定版本
    vscode vue 去掉语法提示
    elasticsearch regexp查询特殊字符处理
    redis中获取不同自增数的方法
    java Elasticsearch 进行嵌套子聚合
  • 原文地址:https://www.cnblogs.com/wangbin/p/10468436.html
Copyright © 2020-2023  润新知