使用要点

边缘模式(ET)与水平模式(LT)区别

下面内容来自linux man page

The  epoll event distribution interface is able to behave both as edge-triggered (ET) and as level-triggered (LT).  The difference between he two mechanisms can be described as follows.  Suppose that this scenario happens:
1. The file descriptor that represents the read side of a pipe (rfd) is registered on the epoll instance.
2. A pipe writer writes 2 kB of data on the write side of the pipe.
3. A call to epoll_wait(2) is done that will return rfd as a ready file descriptor.
4. The pipe reader reads 1 kB of data from rfd.
5. A call to epoll_wait(2) is done. If the rfd file descriptor has been added to the epoll interface using the EPOLLET (edge-triggered) flag, the call to epoll_wait(2) done in step 5 will probably hang despite the available data still present in the file input buffer; meanwhile the remote peer might be expecting a response based on the data it already sent. The reason for this is that edge-triggered mode delivers events only when changes occur on the monitored file descriptor. So, in step 5 the caller might end up waiting for some data that is already present inside the input buffer. In the above example, an event on rfd will be generated because of the write done in 2 and the event is consumed in 3. Since theread operation done in 4 does not consume the whole buffer data, the call to epoll_wait(2) done in step 5 might block indefinitely.

简单来说,如果使用ET模式,对于同一个事件,内核只会上报一次。如果代码没有读取完所有可读取的数据,然后继续调用epoll_wait那么是不会收到事件的。ET模式一般要设定成setnonblocking模式,并且等到读取数据返回EAGAIN或者

如果使用LT模式,则调用epoll_wait后会继续有事件触发。LT模式与poll保持一样的语义,区别是比poll的性能更好一些。

读取数据要点

  • 对于流式连接,例如pipe、fifo、tcp等,通过判定read的返回值比指定读取的小,来判断缓冲区中的数据已经读完了
  • 对于数据报,例如udp等,则通常需要需要持续读取到EAGAIN返回,才能判断缓冲区数据已经读完了
  • 每次从epoll_wait返回后都需要调用epoll_ctl往epoll中继续增加事件

惊群问题解决

  • EPOLLEXCLUSIVE 当多个fd指向同一个文件,并且都被添加到epoll中,那么就可能产生惊群问题:一旦这个文件有被写入,那么read事件会触发给多个fd。加了这个标志后,保证至少一个能收到事件。

ET模式下的饥饿现象

某一个文件,可能来的数据非常多,持续的多,那么这个文件会不停的进行read(按照我们前面说的返回EAGAN或者返回小于指定大小的思路)。由于整个运行时单线程的,那么其他fd就会一直等待,造成了所谓的饥饿现象

epoll的饥饿模式如何避免?linux man page中给出的答案时,不直接在epoll_wait返回后直接读取数据,而是将可读的fd放到一个list里面。然后再对这个list中的fd分别执行read,可以通过限制每个fd一次read的字节数来控制切换到其他fd,当一个fd 读完后从list删除掉。

处理使用 epoll ET 模式下文件描述符出现饥饿的情况_epoll wait防饥饿-CSDN博客

句柄数限制

/proc/sys/fs/epoll/max_user_watches 中记录系统范围内,限制加入到epoll中的句柄数,实际上是限制句柄相关的内存(64位下160字节,32位下90字节)最多只能占用内存的4%。

内核实现原理

epoll_wait是如何实现的

  • 用户调用epoll_wait,会通过syscall指令执行系统调用
  • 系统调用统一入口根据系统调用号走到内核对应的sys_epoll_wait处理函数(内核用call指令 执行)
  • 然后回判断epoolfd里面关联的文件句柄是否有可读的句柄
  • 如果暂时没有那么epoll_wait线程就会等待在这些句柄的queue上
  • 一旦这些文件句柄(例如socket),有数据进来后,内核的ksoftirqd线程会尝试唤醒线程,并从上次线程切换的位置宠幸执行sys_epoll_wait

注意:

  • epoll_ctl会将epollfd加入到io句柄的等待队列中

参考资料

epoll使用与原理的更多相关文章

  1. 深入理解NIO(四)—— epoll的实现原理

    深入理解NIO(四)—— epoll的实现原理 本文链接:https://www.cnblogs.com/fatmanhappycode/p/12362423.html 终于来到最后了,万里长征只差最 ...

  2. Linux下select&poll&epoll的实现原理(一)

    最近简单看了一把 linux-3.10.25 kernel中select/poll/epoll这个几个IO事件检测API的实现.此处做一些记录.其基本的原理是相同的,流程如下 先依次调用fd对应的st ...

  3. Linux下select&poll&epoll的实现原理(一)【转】

    转自:http://www.cnblogs.com/lanyuliuyun/p/5011526.html 最近简单看了一把 linux-3.10.25 kernel中select/poll/epoll ...

  4. epoll详细工作原理(转)

    原文:没有找到出处 开发高性能网络程序时,windows开发者们言必称iocp,linux开发者们则言必称epoll.大家都明白epoll是一种IO多路复用技术,可以非常高效的处理数以百万计的sock ...

  5. linux epoll的实现原理

    1 linux的poll操作 linux文件的poll操作有两个主要目的:第一,主动查看该文件上是否有读写事件:第二,提供操作waitqueue的接口给epoll等上层接口使用,比如epoll可以通过 ...

  6. [转载] select, poll和epoll的区别

    源地址:http://sheepxxyz.blog.163.com/blog/static/61116213201022003513530/ 随着2.6内核对epoll的完全支持,网络上很多的文章和示 ...

  7. 【转载】epoll的使用

    select,poll,epoll简介 select select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理.这样所带来的缺点是: 1 单个进程可监视的fd数量被限制 2 需要维 ...

  8. 深入了解epoll (转)

    一. 介绍 Epoll 是一种高效的管理socket的模型,相对于select和poll来说具有更高的效率和易用性.传统的select以及poll的效率会因为 socket数量的线形递增而导致呈二次乃 ...

  9. 为什么epoll会那么高效

    参考(原文简直超赞):https://zhidao.baidu.com/question/687563051895364284.html下面是我结合原文写的,为了便于自己理解:关于阻塞和非阻塞的理解可 ...

  10. nginx中的epoll模型

    要了解epoll模型,就要一个一个知识点由浅至深地去探索. 1.IO复用技术 IO流请求操作系统内核,有串行处理和并行处理两种概念. 串行处理是前面一个操作处理地时候,后面的所有操作都需要等待.因此, ...

随机推荐

  1. 性能提升40%!阿里云神龙大数据加速引擎获TPCx-BB世界排名第一

    ​简介:神龙大数据加速引擎,针对大数据常用组件,如Spark.Hadoop.Alluxio等,结合阿里云神龙架构的特性,进行软硬一体化优化,形成独一无二的性能优势,最终,使复杂SQL查询场景性能相比社 ...

  2. 阿里的 RocketMQ 如何让双十一峰值之下 0 故障?

    简介: 2020 年双十一交易峰值达到 58.3 W 笔/秒,消息中间件 RocketMQ 继续数年 0 故障丝般顺滑地完美支持了整个集团大促的各类业务平稳. 作者 | 愈安来源 | 阿里巴巴云原生公 ...

  3. 技术干货 | 闲鱼:一个优秀的 Push 平台,需要经历怎样的前世今生

    ​简介: mPaaS 消息推送服务,快速集成多家厂商 Push 通道,有效提高用户留存率,提升用户体验. 编者荐语: 点击这里,了解 mPaaS 消息推送服务,快速集成多家厂商 Push 通道,有效提 ...

  4. [FAQ] puppeteer 清空输入框的值 并 重新输入

    一种方式是,清空输入框可以通过如下注入代码实现,但是可能存在 和页面本身的操作 存在优先级问题. await page.evaluate( () => document.getElementBy ...

  5. [Trading] 专业交易: 专业交易员和散户交易员的不同, 什么是专业交易员

    专业交易员可能用的是公司的钱或者自己的钱 有基本工资支持,散户用的是自己的钱 没有人提供工资来做交易. 目标不同,专业交易员的目的是增长投资账户和获得奖金,散户大部分是为了提取盈利收入而无法增长投资账 ...

  6. C#类型后加问号?

    C# 可空类型(Nullable)说明_w3cschool 细说Nullable<T>类型 - Sweet-Tang - 博客园 (cnblogs.com) 值类型变量不能null,加问号 ...

  7. 使用 Docker 自建一款怀旧游戏之 - 超级马里奥

    1)超级马里奥 简介 < 超级马里奥 >(Super Mario)是任天堂公司创造的一款经典游戏系列,是世界上最知名.最成功的游戏之一.这个系列由日本设计师宫本茂于 1985 年创造,最初 ...

  8. 和 ChatGPT 聊聊 .NET 编译和执行背后的那些事儿

    1 .NET 编译.构建.执行涉及到哪些概念 在 .NET 编译.构建和执行中,涉及到以下概念: C# 或 Visual Basic .NET 等编程语言: 这些是 .NET Framework 使用 ...

  9. 创建第一个springmvc程序

    创建第一个springmvc程序 1.创建父项目文件,导入依赖,删除src文件夹 pom.xml文件 <dependencies> <dependency> <group ...

  10. python教程6.2-OS模块random模块

    OS模块  random模块