【linux高级IO(三)】初识epoll

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:Linux从入门到精通

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵带你学更多操作系统知识
  🔝🔝


1. 前言

其实在select和epoll之间还夹了一个poll, 但是由于epoll过于优秀, 所以poll基本没人使用(甚至没有select使用的多), 这里就直接跳过poll了, epoll本质上也是一种多路转接的实现方案

本章重点:

本篇文章着重讲解epoll的概念和它的底层原理, 最后会讲解epoll的两种工作模式: ET模式和LT模式, 本篇文章没有epoll编码, 全是干货概念


2. 初识epoll

在centos下的man手册中, 对epoll是这样介绍的: 是为处理大批量句柄而作了改进的poll, 相信聪明的你一定发现了, select和poll的编程非常麻烦, 它需要我们程序员自行维护一些数据结构, 并且还有输入输出型参数, 编程成本高, 并且学习成本也高. 所以有了epoll

epoll相关的三个系统调用:

在这里插入图片描述

epoll_create, 用于创建epoll模型

在这里插入图片描述

epoll_ctl,用于设置关心的文件描述符和关心的事件

events可以是以下几个宏的集合:

  • EPOLLIN : 表示对应的文件描述符可以读 (包括对端SOCKET正常关闭);
  • EPOLLOUT : 表示对应的文件描述符可以写;
  • EPOLLPRI : 表示对应的文件描述符有紧急的数据可读 (这里应该表示有带外数据到来);
  • EPOLLERR : 表示对应的文件描述符发生错误;
  • EPOLLHUP : 表示对应的文件描述符被挂断;
  • EPOLLET : 将EPOLL设为边缘触发(Edge Triggered)模式, 这是相对于水平触发(Level Triggered)来说的.
  • EPOLLONESHOT:只监听一次事件, 当监听完这次事件之后, 如果还需要继续监听这个socket的话, 需要再次把这个socket加入到EPOLL队列里…

在这里插入图片描述

epoll_wait,用于等待是否有事件就绪


3. epoll的工作原理

当程序中调用epoll_create时, 会在底层创建一个eventpoll结构体, 此结构体中有两个非常重要的字段:

  • 一颗红黑树的根节点指针
  • 一个队列的头指针

红黑树的用处:

红黑树中存放着所有正在关心的文件描述符, 当我们调用epoll_ctl设置关心事件时, 实际上会在底层的这颗红黑树中添加/删除/修改节点

队列的用处:

队列中存放的是所有存在就绪事件的文件描述符, 当我们调用epoll_wait时, 实际上就是在等待此队列中是否有就绪的文件描述符到来

关于epoll的几个细节:

  1. 红黑树的节点是需要key值的, 而文件描述符恰好可以充当这一值
  2. 用户只需要设置关心, 获取结果即可, 不用再关心任何对fd和event的管理
  3. 底层只要有fd就绪, OS会自动给我构建节点, 并且插入到就绪队列中, 上层只需不断从就绪队列中将数据拿走, 就完成了获取就绪事件的任务(生产者消费者模型)

在这里插入图片描述

struct epitem{ 
 struct rb_node rbn;//红黑树节点 
 struct list_head rdllink;//双向链表节点 
 struct epoll_filefd ffd; //事件句柄信息 
 struct eventpoll *ep; //指向其所属的eventpoll对象 
 struct epoll_event event; //期待发生的事件类型 
}

当调用epoll_wait检查是否有事件发生时,只需要检查eventpoll对象中的rdlist双链表中是否有epitem元素即可. 如果rdlist不为空,则把发生的事件复制到用户态,同时将事件数量返回给用户. 这个操作的时间复杂度是O(1)

总结一下, epoll的使用过程就是三部曲:

  • 调用epoll_create创建一个epoll句柄;
  • 调用epoll_ctl, 将要监控的文件描述符注册到红黑树;
  • 调用epoll_wait, 等待文件描述符就绪后, 去队列中拿;

4. epoll的优缺点

对比select的优点:

  • 接口使用方便: 虽然拆分成了三个函数, 但是反而使用起来更方便高效. 不需要每次循环都设置关注的文件描述符, 也做到了输入输出参数分离开
  • 数据拷贝轻量: 只在合适的时候调用 EPOLL_CTL_ADD 将文件描述符结构拷贝到内核中, 这个操作并不频繁(而select/poll都是每次循环都要进行拷贝)
  • 事件回调机制: 避免使用遍历, 而是使用回调函数的方式, 将就绪的文件描述符结构加入到就绪队列中,
  • epoll_wait 返回直接访问就绪队列就知道哪些文件描述符就绪. 这个操作时间复杂度O(1). 即使文件描述符数目很多, 效率也不会受到影响.
  • 没有数量限制: 文件描述符数目无上限.

正是上诉的优点,使得epoll成为了现代高并发服务器中, 使用的最多的方法, 没有之一!


5. epoll的工作模式

epoll有两种工作方式:

  • 水平触发(LT模式)
  • 边缘触发(ET模式)

水平触发模式讲解:

想象一下你一次性买了5个快递, 快递员张三把快递送到你家楼下了, 打电话让你下来拿快递, 但是这个时候你正在和室友开黑, 你就对快递员说: 你等等我, 我打完这把就下来取, 张三也没说什么, 就在楼下等你. 你终于打完了这把游戏, 现在你下去取快递, 但是你一次性只能拿4个快递, 还剩一个在下面, 你给快递员张三说: 你能不能再等我一下, 我上楼后再下来取剩下的一个快递, 张三也没说什么, 就在楼下等你. 你不下来取, 张三就一直等你, 一直给你打电话.

这就是水平触发模式:

在这里插入图片描述

聪明的你也能想到, 水平触发模型下, 效率会很低, 因为快递员张三一直在楼下等你, 不能做其他事, 所以有了边缘触发来替代它

边缘触发模式详解:

想象一下, 假设是李四给你送外卖, 他和张三不一样, 他脾气非常火爆, 你快递到来后他给你打了个电话说: 你快递到了, 我只等你十分钟, 如果你不下楼取快递, 我就把你的快递放在路边了, 并且我只给你打一次电话. 这个时候你会怎么办? 当然你会选择挂机坑队友, 直接跑下楼取快递, 因为你不去你的快递可能就丢失了!

这就是边缘触发模型:

在这里插入图片描述


6. ET模式和LT模式的对比

首先, 一定是ET模式更加高效.
具体表现为下面几点:

  1. ET模式通知用户的次数变少, 减少了从内核态到用户态的转换, 提高了效率
  2. ET模式会使程序员一次性将所有数据取走, 减少了拷贝的次数
  3. ET模式会倒逼程序员尽快将接收缓冲区的数据取走, 那么就可以给对方发送一个更大的接受窗口(TCP协议), 对方就可以有一个更大的滑动窗口, 一次性给我们发送更多数据, 提高IO吞吐量

7. 总结以及拓展

本篇文章是epoll的理论知识, 后面会带大家实践编写代码, 如果你对epoll感兴趣, 你可以去了解一下reactor模式, 也称为反应堆模式, 很多大型框架的底层都是通过reactor来提高服务器效率的!


相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-17 12:24:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-17 12:24:02       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-17 12:24:02       58 阅读
  4. Python语言-面向对象

    2024-07-17 12:24:02       69 阅读

热门阅读

  1. ETG2000 5.3.9.2 Offline Dictionary DictionaryFile路径

    2024-07-17 12:24:02       24 阅读
  2. 数学归纳法

    2024-07-17 12:24:02       19 阅读
  3. Python基础:register buffer

    2024-07-17 12:24:02       23 阅读
  4. android.app.application can not be cast to android.app.Activity

    2024-07-17 12:24:02       21 阅读
  5. 优化Conda环境:深入掌握conda clean命令的清理艺术

    2024-07-17 12:24:02       23 阅读
  6. 探索Conda的搜索能力:挖掘Python包的宝藏

    2024-07-17 12:24:02       28 阅读
  7. conda 环境打包与使用

    2024-07-17 12:24:02       30 阅读
  8. C语言——练习:将数组中的n个元素按逆序存放

    2024-07-17 12:24:02       23 阅读
  9. django form 将表单数据发送到后端触发弹窗

    2024-07-17 12:24:02       31 阅读
  10. 什么样的服务器是合乎直销网站标准

    2024-07-17 12:24:02       19 阅读