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

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

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

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

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


Linux高级IO

  • 1. 前言
  • 2. 初识epoll
  • 3. epoll的工作原理
  • 4. epoll的优缺点
  • 5. epoll的工作模式
  • 6. ET模式和LT模式的对比
  • 7. 总结以及拓展

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来提高服务器效率的!


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/45890.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STM32 HRTIM生成PWM时遇到无法输出PWM脉冲波形问题

在使用HRTIM生成PWM时,当把周期寄存器更新的设置放到while循环中时,无法输出PWM脉冲波形,即使增加计数延时也无法输出,最终只能放到中断函数中执行后期寄存器值更新才能够生成PWM脉冲波形。

主流大数据调度工具DolphinScheduler之数据ETL流程

今天给大家分享主流大数据调度工具DolphinScheduler,以及数据的ETL流程。 一:调度工具DS 主流大数据调度工具DolphinScheduler, 其定位:解决数据处理流程中错综复杂的依赖关系 任务支持类型:支持传统的shell任务&a…

冷却塔由那些配件组成

1、淋水填料 将需要冷却的水(热水)多次溅洒成水滴或形成水膜,以增加水和空气的接触面积和时间,促进水和空气的热交换。 填料在开式横流冷却塔的作用是增加循环水与空气的接触面积,并延长冷却水停留在空气中的时间&am…

LabVIEW工业设备姿态监测系统

开发了一种基于LabVIEW的工业设备姿态监测系统,针对现有监测设备在适应性和反应时间上的不足,采用了LabVIEW软件和STM32微控制器,通过高精度姿态传感器实现了对设备姿态的快速准确监测,大大提高了工业作业的安全与效率。 项目背景…

C++深度解析教程笔记9-静态成员变量,静态成员函数,二阶构造,友元,函数重载,操作符重载

C深度解析教程笔记9 第25课 - 类的静态成员变量实验-数对象个数(失败)实验-静态变量小结 第26课 - 类的静态成员函数实验-修改对象的静态变量数值实验-利用静态成员函数实验-静态变量静态函数实现统计对象个数小结 第27课 - 二阶构造模式实验-初始化是否…

百度人脸识别Windows C++离线sdk C#接入

百度人脸识别Windows C离线sdk C#接入 目录 说明 设计背景 • 场景特点: • 客户特点: • 核心需求: SDK 包结构 效果 代码 说明 自己根据SDK封装了动态库,然后C#调用。 功能接口 设计背景 • 场景特点: -…

支持前端路由权限和后端接口权限的企业管理系统模版

一、技术栈 前端:iview-admin vue 后端:springboot shiro 二、基于角色的权限控制 1、路由权限 即不同角色的路由访问控制 2、菜单权限 即不同角色的菜单列表展示 3、按钮权限 即不同角色的按钮展示 4、接口权限 即不同角色的接口访问控制 三…

数字化时代的生产革新:数字孪生平台如何助力新质生产力

一.新质生产力 在当今快速发展的科技和信息时代,企业和组织在提高生产效率和质量方面面临着越来越多的挑战和机遇。新质生产力的概念应运而生,强调通过创新和技术进步,不仅提升生产的数量和速度,更重要的是优化生产方式、改善产品…

leetcode热题100.分割等和子集(动态规划)

分割等和子集 Problem: 416. 分割等和子集 思路 我选择使用动态规划的方法来解题。我们需要判断是否可以将数组分割成两个子集,使得这两个子集的和相等。这个问题可以转化为在数组中找到一个子集,使得其和等于数组总和的一半。 解题过程 首先&#xf…

图——图的应用02最短路径(Dijkstra算法与Floyd算法详解),拓扑排序及关键路径

前面介绍了图的应用——01最小生成树章节,大家可以通过下面的链接学习: 图——图的应用01最小生成树(Prim算法与Kruskal算法详解) 今天就讲一下图的其他应用——最短路径,拓扑排序及关键路径。 目录 一&#xff0c…

成都亚恒丰创教育科技有限公司 【插画猴子:笔尖下的灵动世界】

在浩瀚的艺术海洋中,每一种创作形式都是人类情感与想象力的独特表达。而插画,作为这一广阔领域中的璀璨明珠,以其独特的视觉语言和丰富的叙事能力,构建了一个又一个令人遐想连篇的梦幻空间。成都亚恒丰创教育科技有限公司 在众多插…

Linux——进程概念详解

一、进程的基本概念 在给进程下定义之前,我们先了解一下进程: 我们在编写完代码并运行起来时,在我们的磁盘中会形成一个可执行文件,当我们双击这个可执行文件时(程序时),这个程序会加载到内存…

动手学深度学习6.3 填充和步幅-笔记练习(PyTorch)

以下内容为结合李沐老师的课程和教材补充的学习笔记,以及对课后练习的一些思考,自留回顾,也供同学之人交流参考。 本节课程地址:填充和步幅_哔哩哔哩_bilibili 代码实现_哔哩哔哩_bilibili 本节教材地址:6.3. 填充和…

自建Web网站部署——案例分析

作者主页: 知孤云出岫 目录 作者主页:如何自建一个Web网站一、引言二、需求分析三、技术选型四、开发步骤1. 项目初始化初始化前端初始化后端 2. 前端开发目录结构示例代码App.jsHome.js 3. 后端开发目录结构示例代码app.jsproductRoutes.jsProduct.js 4. 前后端连接安装axio…

泛微e-cology WorkflowServiceXml SQL注入漏洞(POC)

漏洞描述: 泛微 e-cology 是泛微公司开发的协同管理应用平台。泛微 e-cology v10.64.1的/services/接口默认对内网暴露,用于服务调用,未经身份认证的攻击者可向 /services/WorkflowServiceXml 接口发送恶意的SOAP请求进行SQL注入,…

使用JS和CSS制作的小案例(day二)

一、写在开头 本项目是从github上摘取,自己练习使用后分享,方便登录github的小伙伴可以看本篇文章 50项目50天​编辑https://github.com/bradtraversy/50projects50dayshttps://github.com/bradtraversy/50projects50days有兴趣的小伙伴可以自己去gith…

面向对象七大原则

学习目标 了解面向对象七大原则基本概念。 在之后实践应用中,要给予七大原则去设计程序。 为什么有七大原则 七大原则总体要实现的目标是: 高内聚、低耦合。 使程序模块的可重复性、移植性增强。 高内聚低耦合 从类角度来看,高内聚低…

如何在Linux上部署Ruby on Rails应用程序

在Linux上部署Ruby on Rails应用程序是一个相对复杂的过程,需要按照一系列步骤进行。下面是一个基本的部署过程,涵盖了从安装所需软件到部署应用程序的所有步骤。 安装必要的软件 在部署Ruby on Rails应用程序之前,需要确保Linux系统上安装了…

AI网络爬虫023:用deepseek批量提取天工AI的智能体数据

文章目录 一、介绍二、输入内容三、输出内容一、介绍 天工AI的智能体首页: F12查看真实网址和响应数据: 翻页规律: https://work.tiangong.cn/agents_api/square/sq_list_by_category?category_id=7&offset=0 https://work.tiangong.cn/agents_api/square/sq_list_b…

08 模型演化根本 深度学习推荐算法的五大范式

易经》“九三:君于终日乾乾;夕惕若,厉无咎”。九三是指阳爻在卦中处于第三位,已经到达中位,惕龙指这个阶段逐渐理性,德才已经显现,会引人注目;但要反思自己的不足,努力不…