当前位置: 首页 > news >正文

epoll

目录

epoll的接口

epoll_create/epoll_create1

epoll_ctl

epoll_wait

epoll的原理

ET/LT模式


epoll的接口

epoll的目的是多个fd(io)事件的等待机制,达到事件派发的目的,就是当事件到达网卡的时候,每个 socket 的 struct sock 中有一个等待队列(如 sk->sk_sleep)。当 socket 收到数据(TCP 数据到达网卡 → 内核协议栈 → socket 接收缓冲区),内核会唤醒该 socket 的等待队列。epoll 通过回调机制ep_poll_callback)被触发,将就绪事件通知给用户空间,完成就绪事件的通知机制。

epoll_create/epoll_create1

epoll_create1() 是 Linux 2.6.27 起新增的系统调用,用来创建一个新的 epoll 实例并返回其文件描述符。它与早期 epoll_create(int size) 的唯一区别就在于 多了一个 flags 参数,从而可以携带额外的创建选项。我们要使用epoll进行多路转接的提醒机制首先需要先创建一个epoll模型。

epoll_create(int size)最早期的 epoll 实例创建接口,出现于 Linux 2.5.44,2.6 内核后正式稳定。

这个flag就是填写的如上两个宏,填写非0的那个更安全

这个size已经失去作用了,所以size随便填一个值都可以的,我们一般填256

epoll_ctl

epoll_ctl 是 epoll 三部曲(create → ctl → wait)中唯一用来增删改被监控 fd 的系统调用。
一句话:把 socket(或其他 fd)挂到 epoll 红黑树上,或从树上摘除

epoll_ctl的作用就是向一个epoll模型中添加fd和关心的事件,告诉内核你要帮我关心哪些fd上的哪些事件(可读,可写)

我们通过op宏操作将后面的event挂到挂满event的红黑树上,然后在event里面的data设置提示是哪个fd,然后events是位图设置宏要关心哪个事件。在event里面设置fd是为了在 epoll_wait 返回后,快速知道是哪个 fd 就绪,避免再查表,在外独立传一次fd是为了告诉内核要关心哪个fd。这个两个fd的作用不一样的。

所以epoll_ctl的作用就是设置关心的fd及其关心事件。epoll_ctl 成功返回 0,失败返回 -1 并设置 errno

epoll_wait

epoll_wait 是 epoll 事件循环的“最后一公里”:让内核把已经就绪的文件描述符一次性交给你

event是一个输出参数,就是内核告诉你历史上哪些fd上的哪些事件已经就绪了。说明之前epoll_ctl联入红黑树的关联fd节点,当fd准备就绪时其同时属于输出数组上的节点。

这个maxevents是你给 epoll_wait 的“输出缓冲区”长度,填多少完全取决于你能一次性“扛”多少事件,别搞溢出就行。如果就绪事件 > MAX这次只拿 MAX 个,剩下的下次 epoll_wait 再给你,其值必须大于0。

timeout同poll

epoll的原理

入上图,epoll作为内核的一种一个回调callback方式,当有事件通过网卡的时候,内核会回调存在进程的void* private data里面的epoll,来处理提醒关心这个io事件,这时进程创建一个epoll模型,然后基于这个epoll模型调用epoll_ctl方法将用户指定的event通过op宏方法联入/删除等等操作调入早已经生成的储存要关心的事件的红黑树,为什么用红黑树呢,因为增删查的效率一般情况下都比数组高,然后接着当有事件就绪的时候,调用epoll_wait将其联入输出数组中,将用户指定长度从0开始交付给用户。

细节1:对于epoll来说储存fd的红黑树相当于辅助数组。

细节2:fd节点是共同存在红黑树和就绪队列中的,不需要考虑迁移的问题

细节3:红黑树中的key值是fd的值

细节4:Linux 内核把“epoll 实例”实现成一个 特殊的匿名文件(anon-inode 文件)
fd 是用户空间访问任何内核文件对象的统一句柄——这就是epoll模型必须返回 fd 的根本原因Linux下一切皆文件

epoll为什么高效,因为用户只需要注册进去,os自己驱动,就绪之后也不需要轮询判断,自动传出就绪的事件了。

ET/LT模式

LT(默认):只要 fd 上的事件“仍然成立”,epoll_wait 就每次都会告诉你,所以这种情况可以随意的反复的根据epoll就绪信号反复读取,这个也是epoll模型就默认形式。

ET:只有 fd 上的事件“从无到有”变化的那一刻才通知一次,之后不管数据是否剩余,都不再通知,直到下一次“新数据到达”再次触发。这时就逼着我们去一次性反复的读取并且通过协议判断是否读完。

记住上面的三,四。

由于ET模式算fd上需要关心的事件,所以将fd的读/写事件设置成ET模式,需要在原本关心的事件上|EPOLLET。LT+非阻塞+循环读取=ET

LT作为基本情况的使用,ET是基于高吞吐量的io设计的。


文章转载自:

http://AvDclehx.jhgxh.cn
http://mCFBMaIs.jhgxh.cn
http://KUpDA5Mg.jhgxh.cn
http://Qk1YohDk.jhgxh.cn
http://XULL7wgq.jhgxh.cn
http://i3HijBen.jhgxh.cn
http://XcZe9Pkd.jhgxh.cn
http://amEJBGSV.jhgxh.cn
http://Guwo6YzT.jhgxh.cn
http://lKO2eUBR.jhgxh.cn
http://8S88GzTC.jhgxh.cn
http://nfPLlUwv.jhgxh.cn
http://fQaKb6Rw.jhgxh.cn
http://KPzze7mn.jhgxh.cn
http://xQ2Wds7q.jhgxh.cn
http://0OsdiHFi.jhgxh.cn
http://4r5NuSwc.jhgxh.cn
http://4JuHsyzp.jhgxh.cn
http://C4egHDVi.jhgxh.cn
http://WLUg6SrF.jhgxh.cn
http://HF8rt2V0.jhgxh.cn
http://YQU1Xdkt.jhgxh.cn
http://zmSaFNrd.jhgxh.cn
http://F4BUvhLo.jhgxh.cn
http://OUnAGtCK.jhgxh.cn
http://5LvH3mkS.jhgxh.cn
http://oygSkcWV.jhgxh.cn
http://HfYCtr9l.jhgxh.cn
http://krP6TzXd.jhgxh.cn
http://uPtN8Nl6.jhgxh.cn
http://www.dtcms.com/a/370661.html

相关文章:

  • 淘宝拍立淘按图搜索及淘宝API(JSON数据返回)核心解析
  • 机器人控制器开发(定位算法——map、odom、baselink关联与差异)
  • Python 多线程与多进程入门指南
  • 分布式评估 AUC 乱飞
  • spring boot + mybatis 使用线程池异步修改数据库数据
  • redission实现读写锁的原理
  • 室内植物光照初学者指南
  • Redisson分布式锁:看门狗机制与续期原理
  • OSG工具集
  • CC内存管理深度解析从内存布局到newdelete的底层实现
  • 让机器具有主动性-主动性算法[01]
  • PagedAttention:突破大语言模型内存瓶颈的分页式注意力革命
  • Qt 中的 Q_OBJECT 宏详解 —— 从源码到底层机制的全面剖析
  • 正态分布 - 计算 Z-Score 的 无偏估计
  • 【基础-单选】用哪一种装饰器修饰的struct表示该结构体具有组件化能力?
  • 【LeetCode 每日一题】2348. 全 0 子数组的数目
  • 《2025国赛/高教杯》C题 解题思路 NIPT的时点选择与胎儿的异常判定
  • vspere 服务的部署介绍
  • 基本数据类型和包装类的区别?
  • 《AC影》正史模式引争议 育碧回应希望激发历史兴趣
  • leetcode30.串联所有单词的子串
  • QML Charts组件之LineSeries、SplineSeries与ScatterSeries
  • browser-use 的三种启动方式详解
  • Qt对话框与文件操作学习
  • Linux文件管理器选择与推荐
  • 接雨水问题解析:双指针与单调栈解法
  • Kafka Exactly-Once 语义深度解析与性能优化实践指南
  • spring-ai-alibaba-deepresearch 学习(十三)——ResearcherNode
  • 2、数学与经济管理
  • 使用 Shell 脚本监控服务器 IOWait 并发送邮件告警