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

epoll的LT和ET(转)的更多相关文章

  1. 从I/O复用谈epoll为什么高效

    上一篇文章中,谈了一些网络编程的基本概念.在现实使用中,用的最多的就是I/O复用了,无非就是select,poll,epoll 很多人提到网络就说epoll,认为epoll效率是最高的.单纯的这么认为 ...

  2. select、poll、epoll之间的区别总结

    select.poll.epoll之间的区别总结 05/05. 2014 select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪 ...

  3. (转载) Linux IO模式及 select、poll、epoll详解

    注:本文是对众多博客的学习和总结,可能存在理解错误.请带着怀疑的眼光,同时如果有错误希望能指出. 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案 ...

  4. linux下select/poll/epoll机制的比较

    select.poll.epoll简介 epoll跟select都能提供多路I/O复用的解决方案.在现在的Linux内核里有都能够支持,其中epoll是Linux所特有,而select则应该是POSI ...

  5. epoll LT/ET 深度剖析

    EPOLL事件的两种模型: Level Triggered (LT) 水平触发 .socket接收缓冲区不为空 有数据可读 读事件一直触发 .socket发送缓冲区不满 可以继续写入数据 写事件一直触 ...

  6. 非阻塞/异步(epoll) openssl

    前段时间在自己的异步网络框架handy中添加openssl的支持,当时在网络上搜索了半天也没有找到很好的例子,后来自己慢慢的摸索,耗费不少时间,终于搞定.因此把相关的资料整理一下,并给出简单的例子,让 ...

  7. select,epoll,poll比较

    介绍和比较 http://www.cnblogs.com/maociping/p/5132583.html 比较 http://www.dataguru.cn/thread-336032-1-1.ht ...

  8. Linux epoll

    一. epoll函数集 epoll主要有三个函数: 1. int epoll_create(int size); 创建一个epoll的句柄,size用来告诉内核这个监听的数目一共有多大.这个参数不同于 ...

  9. linux下epoll实现机制

    linux下epoll实现机制 原作者:陶辉 链接:http://blog.csdn.net/russell_tao/article/details/7160071 先简单回顾下如何使用C库封装的se ...

  10. select、poll、epoll之间的区别总结[整理]

    select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作.但select ...

随机推荐

  1. @MapperScan使用

    @MapperScan:要扫描mapper类包的路径 还可以扫描多个包,如: @MapperScan({"com.kfit.demo","com.kfit.user&qu ...

  2. 【webdriver自动化】将163登录邮箱的操作封装成多个方法去执行

    login_info.txt: youxiang_99@163.com,XXXX youxiang_100@163.com,XXXX main.py: #注意:编码格式 #算法: (1)定义多个方法, ...

  3. Makefile 中 -rpath -rpath-link

    -rpath和-rpath-link 假设有3个文件,在同一目录下,有这样的依赖关系 test->liba.so->libd.so 如果编译test的时候这样写 gcc test.c –l ...

  4. C++ 值传递、指针传递、引用传递详解

    C++ 值传递.指针传递.引用传递详解 最近写了几篇深层次讨论数组和指针的文章,其中提到了“C语言中,所有非数组的形式参数传递均以值传递形式” 数组和指针背后——内存角度 语义"陷阱&quo ...

  5. SSL&TLS渗透测试

    什么是TLS&SSL? 安全套接字层(SSL)和传输层安全(TLS)加密通过提供通信安全(传输加密)和为应用程序如网络.邮件.即时消息和某些虚拟私有网络(VPN)提供隐私的方式来确保互联网和网 ...

  6. 中国商用分组密码SM4

    SM4 密码算法结构 SM4 密码算法基本运算有两部分: 1.模2加:⊕,32比特异或运算 2.循环移位: <<< i ,把32位字循环左移i位 基本密码部件为 1非线性字节变换S盒 ...

  7. Centos6.5安装mariadb的坑坑

    最近在看Ansible,<Ansible权威指南>,然后有个地方是搭建Web应用框架,有个服务器是安装Mariadb,找到官方文档,一直弄,总是报错,换个思路,下载rpm到本地,安装,然后 ...

  8. Nginx中文url出现404问题

    Nginx中文url出现404问题 前提条件检查,如我的系统centos,需要检查系统字符集是不是支持utf-8, 怎么配置可以参考这个帖子 https://www.vpser.net/manage/ ...

  9. 在flask框架中,对wtforms的SelectMultipleField的一个报错处理

    先粘贴代码: form.py文件: users = SelectMultipleField( label="请选择用户", validators=[ DataRequired(&q ...

  10. JDK各个版本的区别

    jdk1.5的新特性: 1. 泛型    ArrayList list=new ArrayList()------>ArrayList<Integer>list=new ArrayL ...