zoukankan      html  css  js  c++  java
  • 浅谈 epoll 中 ET 和 LT 与 阻塞/非阻塞 IO

      epoll 中有两种触发模式,LT (水平触发) 和 ET(边缘触发),网上关于这两种的介绍很多,在这里不多赘述,只简单说下这两种模式下使用 阻塞/非阻塞 IO 的情况,以及对于  “为什么 ET 模式必须使用非阻塞 IO ?” 这个问题的看法。

      个人认为使用 阻塞IO 潜在的问题在于,使用 阻塞 IO 去读的时候,会导致在没有数据可读的时候,导致当前工作线程阻塞不工作。而 ET 模式与 LT 模式都是在有数据的情况下触发,只不过触发的时机不同。假定读缓冲区 50b,而收到的包为 100b,有如下情况:

    • 阻塞 IO

      LT 模式下,由于只要有数据就会触发读,因此不会有问题,但是在 ET 模式下,由于在新的数据到来之前,都不会触发读事件,因此会导致剩下的 50b 没有读取到,所以为了保证能够读取到完整的包,需要使用 while(1) 之类的循环去读,这就会导致在数据读完之后,最后一次 read 阻塞,因为所有的数据都已经读完了。

    • 非阻塞 IO  

      在 LT 模式下,使用非阻塞 IO 的效果与阻塞 IO 差不多,在 ET 模式下,处理的逻辑与上面类似,但是由于使用的 非阻塞 IO ,因此不会导致最后一次 read 阻塞,而是会返回 EAGAIN 。

      最后对于 “为什么 ET 模式必须使用非阻塞 IO ?” 这个问题。我的看法是应该将 “必须” 改成 “建议”,因为如果使用 阻塞IO ,也是有办法规避上面的问题的,比如先获取包体的大小之类的,但是这样也会提高复杂度,效率也会更低下。对于监听的 socket,最好使用 LT 模式,ET 模式会导致高并发情况下,有的客户端会连接不上,除非使用 while 循环 accpet,且为非阻塞 socket 。对于读写的 socket,LT 模式下,阻塞和非阻塞效果都一样。ET 模式下,建议使用非阻塞 IO,并一次性地完整读写全部数据。

  • 相关阅读:
    CentOS6.4 配置mysql服务器启动多个端口,同步单表数据
    生成CSV文件后再将CSV文件导入到mysql
    Quartz Cron 表达式
    Jquery 提示插件alertify 【备用】
    tnsping 命令解析
    Gearman安装及使用
    Redis安装部署
    Linux多网卡负载均衡 : bond
    ulimit命令
    Nginx 负载均衡
  • 原文地址:https://www.cnblogs.com/lawliet12/p/13508057.html
Copyright © 2011-2022 走看看