写在前面

  epoll是开发linux高性能服务器的必备技术至,epoll本质,是服务端程序员的必须掌握的知识。

七、epoll的原理和流程

  本节会以示例和图表来讲解epoll的原理和流程。

创建epoll对象

  如下图所示,当某个进程调用epoll_create方法时,内核会创建一个eventpoll对象(也就是程序中epfd所代表的对象)。eventpoll对象也是文件系统中的一员,和socket一样,它也会有等待队列。内核创建eventpoll对象

  创建一个代表该epoll的eventpoll对象是必须的,因为内核要维护“就绪列表”等数据,“就绪列表”可以作为eventpoll的成员。

维护监视列表

  创建epoll对象后,可以用epoll_ctl添加或删除所要监听的socket。以添加socket为例,如下图,如果通过epoll_ctl添加sock1、sock2和sock3的监视,内核会将eventpoll添加到这三个socket的等待队列中。添加所要监听的socket

  当socket收到数据后,中断程序会操作eventpoll对象,而不是直接操作进程。

接收数据

  当socket收到数据后,中断程序会给eventpoll的“就绪列表”添加socket引用。如下图展示的是sock2和sock3收到数据后,中断程序让rdlist引用这两个socket。给就绪列表添加引用

  

  eventpoll对象相当于是socket和进程之间的中介,socket的数据接收并不直接影响进程,而是通过改变eventpoll的就绪列表来改变进程状态。

  当程序执行到epoll_wait时,如果rdlist已经引用了socket,那么epoll_wait直接返回,如果rdlist为空,阻塞进程。

阻塞和唤醒进程

  假设计算机中正在运行进程A和进程B,在某时刻进程A运行到了epoll_wait语句。如下图所示,内核会将进程A放入eventpoll的等待队列中,阻塞进程。epoll_wait阻塞进程

  当socket接收到数据,中断程序一方面修改rdlist,另一方面唤醒eventpoll等待队列中的进程,进程A再次进入运行状态(如下图)。也因为rdlist的存在,进程A可以知道哪些socket发生了变化。epoll唤醒进程

八、epoll的实现细节

至此,相信读者对epoll的本质已经有一定的了解。但我们还留有一个问题,eventpoll的数据结构是什么样子?

再留两个问题,就绪队列应该应使用什么数据结构?eventpoll应使用什么数据结构来管理通过epoll_ctl添加或删除的socket?

如下图所示,eventpoll包含了lock、mtx、wq(等待队列)、rdlist等成员。rdlist和rbr是我们所关心的。

就绪列表的数据结构

  就绪列表引用着就绪的socket,所以它应能够快速的插入数据。

  程序可能随时调用epoll_ctl添加监视socket,也可能随时删除。当删除时,若该socket已经存放在就绪列表中,它也应该被移除。

  所以就绪列表应是一种能够快速插入和删除的数据结构。双向链表就是这样一种数据结构,epoll使用双向链表来实现就绪队列(对应上图的rdllist)。

索引结构

  既然epoll将“维护监视队列”和“进程阻塞”分离,也意味着需要有个数据结构来保存监视的socket。至少要方便的添加和移除,还要便于搜索,以避免重复添加。红黑树是一种自平衡二叉查找树,搜索、插入和删除时间复杂度都是O(log(N)),效率较好。epoll使用了红黑树作为索引结构(对应上图的rbr)。

ps:因为操作系统要兼顾多种功能,以及由更多需要保存的数据,rdlist并非直接引用socket,而是通过epitem间接引用,红黑树的节点也是epitem对象。同样,文件系统也并非直接引用着socket。为方便理解,本文中省略了一些间接结构。

九、结论

epoll在select和poll(poll和select基本一样,有少量改进)的基础引入了eventpoll作为中间层,使用了先进的数据结构,是一种高效的多路复用技术。

再留一点作业!

下表是个很常见的表,描述了select、poll和epoll的区别。读完本文,读者能否解释select和epoll的时间复杂度为什么是O(n)和O(1)?

IO模型(epoll)--详解-03的更多相关文章

  1. (转)Linux下select, poll和epoll IO模型的详解

    Linux下select, poll和epoll IO模型的详解 原文:http://blog.csdn.net/tianmohust/article/details/6677985 一).Epoll ...

  2. Linux下select, poll和epoll IO模型的详解

    http://blog.csdn.net/tianmohust/article/details/6677985 一).Epoll 介绍 Epoll 可是当前在 Linux 下开发大规模并发网络程序的热 ...

  3. I/O模型之二:Linux IO模式及 select、poll、epoll详解

    目录: <I/O模型之一:Unix的五种I/O模型> <I/O模型之二:Linux IO模式及 select.poll.epoll详解> <I/O模型之三:两种高性能 I ...

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

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

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

    本文为转载,并作了部门调整.修改. [原文出处:https://segmentfault.com/a/1190000003063859] 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么 ...

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

    同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. 本文讨论的背景是Linux环境下的network IO. ...

  7. 网络通信 --> IO多路复用之select、poll、epoll详解

    IO多路复用之select.poll.epoll详解      目前支持I/O多路复用的系统调用有 select,pselect,poll,epoll,I/O多路复用就是通过一种机制,一个进程可以监视 ...

  8. Linux IO模式以及select poll epoll详解

    一 背景 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. 本文讨论的背景是Linux环境下的network ...

  9. 高并发网络编程之epoll详解(转载)

    高并发网络编程之epoll详解(转载) 转载自:https://blog.csdn.net/shenya1314/article/details/73691088 在linux 没有实现epoll事件 ...

  10. Linux下的I/O复用与epoll详解(转载)

    Linux下的I/O复用与epoll详解 转载自:https://www.cnblogs.com/lojunren/p/3856290.html  前言 I/O多路复用有很多种实现.在linux上,2 ...

随机推荐

  1. apicloud 顶部状态栏透明方法

    api.setStatusBarStyle({ style: 'dark', color:'transparent' });

  2. Maven国内源设置

    Maven国内源设置 目前国外的maven源访问非常慢,作为一个Java开发者,是一件很痛苦的事,而国内的maven源,oschina已经关闭,目前最好的方式,就是使用阿里云的镜像: <mirr ...

  3. java:shiro(认证,赋予角色,授权...)

    1.shiro(权限框架(认证,赋予角色,授权...)): readme.txt(运行机制): 1.从jsp的form中的action属性跳转到springmvc的Handler中(controlle ...

  4. yum安装etcd集群

       前一篇文章介绍了如何yum安装简单的kubernetes集群,其中etcd是单点部署.本篇我们来搭建etcd集群,方便日后搭建kubernetes HA集群架构. 1,环境配置说明 etcd1 ...

  5. ORACLE 正则匹配

    1.正则匹配 select CONCAT(TO_NUMBER(REGEXP_REPLACE('019年','[^0-9]')),'年') from dual;

  6. 【Linux开发】linux设备驱动归纳总结(八):2.总线、设备和驱动的关系

    linux设备驱动归纳总结(八):2.总线.设备和驱动的关系 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...

  7. 【Linux开发】linux设备驱动归纳总结(七):1.时间管理与内核延时

    linux设备驱动归纳总结(七):1.时间管理与内核延时 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...

  8. C学习笔记-makefile

    除非最简单的项目,任何一个商业项目都会包含多个源代码,而且在编译的时候会有很长很复杂的指令,为了编译的简单可行,makefile由此而生,在编译时候直接输入make便会按照makefile里面的规则编 ...

  9. Push failed: Failed with error: Could not read from remote repository. IDEA 解决方法

  10. python-redis-订阅和发布

    发布:redishelper.py import redis class RedisHelper: def __init__(self): self.__conn = redis.Redis(host ...