一、epoll底层数据结构

在epoll的使用中,我们经常需要对文件描述符集合进行添加、删除等操作,同时对触发的事件类型进行处理,回调IO事件中的工作函数。这其中离不开两个数据结构的帮助------epitem与eventpoll。

1.1 eventpoll结构体

eventpoll是每一个 epoll所对应的,比如epoll_create()就是创建一个 eventpoll。

内核源码文件中eventpoll的定义如下:

// file:fs/eventpoll.c
struct eventpoll {  //sys_epoll_wait用到的等待队列wait_queue_head_t wq;//接收就绪的描述符都会放到这里struct list_head rdllist;//每个epoll对象中都有一颗红黑树struct rb_root rbr;......
}

其中wq为等待队列链表,软中断数据就绪的时候会通过 wq 来找到阻塞在 epoll 对象上的用户进程。(epoll_wait若就绪队列中无数据,会将当前进程加入到等待队列中)

rdllist标识就绪的文件描述符链表,当有的连接就绪的时候,内核会把就绪的连接放到 rdllist 链表里。这样应用进程只需要判断链表就能找出就绪进程,而不用去遍历整棵树。

rbr为一颗红黑树,采用红黑树的结构为epoll高效的处理海量数据的增删改查,这个红黑树用于管理用户进程添加进来的所有socket连接。

1.2 epitem结构体

epitem是每一个IO所对应的的事件,比如epoll_ctl()中使用EPOLL_CTL_ADD操作的时候,就需要创建一个epitem。

内核源码文件中epitem的定义如下:

// file:fs/eventpoll.c
struct epitem {//红黑树节点struct rb_node rbn;//socket文件描述符信息struct epoll_filefd ffd;//所归属的 eventpoll 对象struct eventpoll *ep;//等待队列struct list_head pwqlist;
}

1.3 epoll_ctl添加socketFd

eventpoll与epitem的联系如下图:

当我们使用epoll_ctl()函数注册一个socket时,内核将会做这些事情:

  1. 分配一个红黑树节点对象epitem
  2. 添加等待事件到socket的等待队列中
  3. 将epitem插入到epoll对象的红黑树中

1.4 epoll_wait等待数据

epoll_wait被调用时会观察 eventpoll->rdllist 链表里有没有数据,有数据就返回,没有数据就创建一个等待队列项,将其添加到 eventpoll 的等待队列上(1.1节中的wait_queue_head_t),然后把自己阻塞掉就完事。

二、epoll的锁机制

epoll在使用时也离不开锁机制的保护,主要的使用场景有:链表操作、红黑树操作、epoll_wait的等待。

2.1 链表操作

链表操作使用的是spinlock自旋锁,当没有竞争到锁资源时,不会睡眠,加快了链表操作的速度,添加和删除操作需要加锁。

2.2 红黑树操作

红黑树操作使用的是互斥锁,在添加和删除操作时需要加锁。

2.3 epoll_wait等待

采用pthread_cond_wait。

三、epoll的回调时机

在前面对epoll底层结构进行梳理之后,那么epoll是如何知道IO事件触发的呢?即epoll怎么知道有就绪fd的?

显然内核协议栈会在特点的时机通过回调函数通知咱们的epoll有IO事件到来,情况如下:

四、LT与ET

epoll的高效还与LT(水平)和ET(边缘)两种模式离不开,下面给出总结如下:

五、epoll与select/poll的对比

  1. 对于select/poll来说,所有的文件描述符都是在用户态被加入集合中,每次调用需要将整个集合拷贝到内核态;epoll则将整个集合维护在内核态,但是每次添加文件描述符的时候需要执行一次系统调用,如果短时间内有大量活跃的连接时,epoll的性能可能不如select/poll。

  2. select使用线性表来描述文件描述符集合,有上限;poll使用链表来描述;epoll则使用红黑树来描述,同时还会维护一个就绪双向链表,用于存放已就绪的事件。

  3. select/poll的主要开销来自内核判断是否有文件描述符就绪的过程,每次执行select/poll调用时,会采用遍历整个集合的方法来判断是否有文件描述符就绪;epoll则不需要,当有事件发生时,会自动触发epoll回调函数通知epoll文件描述符,然后内核将这些就绪的描述符放到双向链表中,等待epoll_wait的调用处理。

  4. 当监测的fd数量较小,且各个fd都很活跃的情况下,建议使用select/poll;当监听的fd数量较多,且单位时间仅部分fd活跃的情况下,使用epoll的性能会很好。

epoll底层原理深究相关推荐

  1. 深究Java中的RMI底层原理

    原博客地址:http://blog.csdn.net/sinat_34596644/article/details/52599688 前言:随着一个系统被用户认可,业务量.请求量不断上升,那么单机系统 ...

  2. mysql引擎层存储层_MySQL存储底层技术:InnoDB底层原理解读

    原标题:MySQL存储底层技术:InnoDB底层原理解读 存储引擎 很多文章都是直接开始介绍有哪些存储引擎,并没有去介绍存储引擎本身.那么究竟什么是存储引擎?不知道大家有没有想过,MySQL是如何存储 ...

  3. 十个问题理解Linux epoll工作原理

    作者:dustinzhou,腾讯 IEG 运营开发工程师 epoll 是 linux 特有的一个 I/O 事件通知机制.很久以来对 epoll 如何能够高效处理数以百万记的文件描述符很有兴趣.近期学习 ...

  4. 面试必备:synchronized的底层原理?

    最近更新的XX必备系列适合直接背答案,不深究,不喜勿喷. 你能说简单说一下synchronize吗? 可别真简单一句话就说完了呀~ 参考回答: synchronize是java中的关键字,可以用来修饰 ...

  5. redis单线程原理___Redis为何那么快-----底层原理浅析

    redis单线程原理 redis单线程问题 单线程指的是网络请求模块使用了一个线程(所以不需考虑并发安全性),即一个线程处理所有网络请求,其他模块仍用了多个线程. 1. 为什么说redis能够快速执行 ...

  6. 十个问题理解Linux epoll工作原理:惊群,

    目录 Question 1:是否所有的文件类型都可以被 epoll 监视?不是 Question 2:ep->wq 的作用是什么? Question 3:什么是 epoll 惊群? Questi ...

  7. Go语言潜力有目共睹,但它的Goroutine机制底层原理你了解吗?

    来源 | 后端技术指南针(ID:gh_ed1e2b37dcb6) Go语言的巨大潜力有目共睹,今天我们来学习Go语言的Goroutine机制,这也可能是Go语言最为吸引人的特性了,理解它对于掌握Go语 ...

  8. IO多路复用底层原理及源码解析

    基本概念 1. 关于linux文件描述符 在Linux中,一切都是文件,除了文本文件.源文件.二进制文件等,一个硬件设备也可以被映射为一个虚拟的文件,称为设备文件.例如,stdin 称为标准输入文件, ...

  9. 图解 epoll 是如何工作的及epoll实现原理

    本文包含以下内容: epoll是如何工作的 本文不包含以下内容: epoll 的用法 epoll 的缺陷 epoll实现原理由视频讲解: C/C++ Linux服务器开发高级架构学习视频点击:C/C+ ...

  10. 后端开发程序员须彻底搞懂的 IO 底层原理

    一.混乱的 IO 概念 IO是Input和Output的缩写,即输入和输出.广义上的围绕计算机的输入输出有很多:鼠标.键盘.扫描仪等等.而我们今天要探讨的是在计算机里面,主要是作用在内存.网卡.硬盘等 ...

最新文章

  1. DeepMind 的新强化学习系统是迈向通用 AI 的一步吗?
  2. 学习jvm(一)--java内存区域
  3. CentOS搭建C++开发环境
  4. 【量化交易】组合优化三部曲:换手率和alpha模型换手约束下的最优模型时变IC下的多空/多头最优组合换手率
  5. python类定义学生信息_Python学生信息管理系统(注释最详细,小白都看的懂)
  6. 女人的安全感到底是什么?
  7. Spring学习总结(12)——Druid连接池及监控在spring配置
  8. 数据结构-树的进化及与数据库的关系
  9. 网页与服务器 — 重定向常见异常状态码
  10. gpu 加速矩阵 深度学习_GPU如何加速深度学习
  11. WebScraper for Mac(网站数据抓取工具)
  12. 维码扫描之集成Zxing
  13. Java 垃圾回收机制原理
  14. 揭秘黑客攻击内幕和20个黑客相关术语
  15. 比色皿洗涤不干净会造成很大实验误差
  16. 计算机硬盘格式化三个步骤,电脑格式化五种操作方法教程
  17. 渗透测试工具-sqlmap
  18. Module not found: Error: [CaseSensitivePathsPlugin]
  19. TSCH协议及WIA-PA系统芯片
  20. arduino 的红外遥控解码

热门文章

  1. 证书服务器,及申请证书。
  2. 量化感知训练_《量化健身 动作精讲》:专业解读健美身材的秘密
  3. 猜数游戏,随机生成一个1~100的数进行猜测。
  4. 2020年如何利用外链提升网站排名和权重?
  5. 数学建模论文的技巧与操作
  6. python程度员要学很多英语吗_为什么程序员应该学好英语?
  7. 面试分享|机械行业面试常见问题有哪些
  8. 海瑞菌的web前端学习直播间
  9. 1880-2010年间全美婴儿姓名
  10. 10 个常见的压力面试问题