reference

https://www.zhihu.com/question/20122137

感谢 @静海听风 @蓝形参

数据流有两个重要的参与者:

1、往流中写入数据者

2、从流中读取数据者

假设两个参与者之间,使用一个缓冲区来存放数据,即a往缓冲区中写入数据,b从缓冲区中读出数据。那么对单个流而言,会存在四种状态:

0、当缓冲区为空时,b阻塞,等待数据到达;

1、当a往缓冲区写入数据时,缓冲区非空,b将被从阻塞状态中唤醒;

2、当a拼命往缓冲区中写入数据,而b没有去读,或读的速度跟不上a写入的速度时,缓冲区满。此时,需要通知a进行阻塞,等待缓冲区中重新腾出空间;

3、当b从缓冲区中读出部分数据后,缓冲区非满,则可以通知a从阻塞状态中醒来;

4、当a不再往缓冲区中写数据,而b一直读,将缓冲区中的数据读完时,将变成缓冲区空,此时通知b进入阻塞状态,等待有数据到来。

当有多个流时,可以考虑用轮训的方式逐一查看每个流目前是否有数据,若有,则进行处理。(非阻塞忙轮询--一直主动查看流的状态)

缺点:cpu空耗在无用的流缓冲区检查上,浪费时间。

改进:引入一个代理人(select),当代理人感知到有一个或多个流的数据有变化时,再进行轮询检查。(非阻塞轮询--有流的状态发生变化时,主动检查所有流的状态)

缺点:当只有一个或少数流有更新时,遍历检查所有的流非常浪费时间。(故,亦称为无差别轮询)

改进:当有流的状态改变时,仅处理该流相关的数据变化。(epoll--event poll,事件轮询,精确到“什么流”发生了“什么事件”)

具体实现是引入了一个红黑树及一个就绪列表。

epoll的关键操作:

1、创建一个epoll对象

epollfd=epoll_create()

此时,会在内核中专属于epoll的高速cache区新建一棵红黑树以及一个就绪列表。

2、往epoll中添加或删除某个流某个事件

epoll_ctl(epollfd, EPOLL_CTL_ADD, socket, EPOLLIN)

epoll_ctl(epollfd, EPOLL_CTL_DEL, socket, EPOLLOUT)

"add"动作会将文件句柄(socket)加入到红黑树中,并向内核注册改句柄的回调函数,当内核检测到该句柄可读或可写时(由中断触发),就将该句柄对应的回调函数加入到就绪列表中。

3、等待事件发生

epoll_wait(epollfd,...)

epoll_wait函数只需要关注就绪列表即可。

当就绪列表中有就绪的socket时,就将这些socket拷贝到用户态,并清空就绪列表。

而后,还会检查这些socket的触法形式(水平出发or边缘触法)

若是水平触发(lt),则若这些socket中还有未处理的事件时,就再把它们加回到就绪列表中;

若是边缘触发(et),则只有当下一次中断到达时,才会把这个socket加回到就绪列表中。

从伪代码上可以更明显的看出三种轮询的区别:

无阻塞忙轮询:

while true{

  for i in stream[]{

    if i has data

      read until unavailable

  }

}

无阻塞轮询(无差别轮询):

while true{

  select(stream[])

  for i in stream[]{

    if i has data

      read until unavailable

  }

}

事件轮询(epoll):

while true{

  active_stream[] = epoll_wait(epollfd)

  for i in active_stream[]{

    read or write until unavailable

  }

}

epoll的由来的更多相关文章

  1. 高性能网络服务器编程:为什么linux下epoll是最好,Netty要比NIO.2好?

    基本的IO编程过程(包括网络IO和文件IO)是,打开文件描述符(windows是handler,java是stream或channel),多路捕获(Multiplexe,即select和poll和ep ...

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

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

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

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

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

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

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

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

  6. epoll LT/ET 深度剖析

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

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

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

  8. select,epoll,poll比较

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

  9. Linux epoll

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

随机推荐

  1. Shell学习之Shell特性(一)

    Shell学习之Shell特性 目录 命令和文件自动补齐功能 命令历史记忆功能 history.上下键.!number.!string.!$.!! 别名功能 alias.unalias cp.~use ...

  2. Linux学习之用户管理命令与用户组管理命令(十五)

    Linux学习之用户管理命令与用户组管理命令 目录 用户管理命令 用户添加命令useradd 修改用户密码passwd 修改用户信息usermod 修改用户密码状态chage 删除用户userdel ...

  3. IntelliJ IDEA关于logger的live template配置

    1.安装 log support2插件 2.配置log support2 由于项目中的日志框架是公司自己封装的,所以还需要自己手动改一下 log support2插件生成的live template ...

  4. iOS 技术篇:如何处理多个网络请求的先后(依赖)关系

    在开发过程中,不知你有没有碰到过在一个页面 用到了多个网络请求,而且根据业务需求,需要有次序的执行A B C 网络请求? 你可能会想到,我在A的请求成功回调里去处理B,在B的回调里去请求C,但你后来会 ...

  5. hihoCoder挑战赛19 A.Rikka with Sequence(状压DP)

    题目链接 比赛链接 \(Description\) \(Solution\) 参考:https://www.cnblogs.com/SovietPower/p/9781573.html 暴力:\(f[ ...

  6. [USACO09JAN]Total Flow

    OJ题号: BZOJ3996.洛谷2936.SPOJ-MTOTALF.SCU3353 思路: 题目的要求是将所有边合并成一条边,求合并后的流量. 实际上相当于直接求最大流. EdmondsKarp模板 ...

  7. BZOJ1166 : [Baltic2008]Magical Stones

    考虑二分答案,转化为求有多少$\leq lim$的数满足条件. 从两侧往中间进行数位DP,设$f[l][r][j][x][y][z][pre][suf]$表示当前准备填的两个位置是$l$和$r$,已经 ...

  8. 《JavaScript-The Definitive Guide》读书笔记:函数定义和函数调用

    定义函数 使用function关键字来定义函数,分为两种形式: 声明式函数定义: function add(m,n) { alert(m+n); } 这种方式等同于构造一个Function类的实例的方 ...

  9. 2016年7款最佳 Java 框架

    毫无疑问,Java 是目前最为流行的编程语言之一,这里我们挖掘出了一些比较受欢迎的框架的有效信息,它们可以减轻全球软件开发人员的日常工作. RebelLabs的一项调查显示,通过在线Java用户论坛( ...

  10. import pandas as pd Python安装pandas模块

    在学习python过程中需要用到一个叫pandas的模块,在pycharm中安装时总是出错. 千般百度折腾还是无果,后来发现它需要安装很多依赖包.就问你气不气~ 需要手动安装啊,千万记住,这里有个py ...