epoll 的用法

简介: 【4月更文挑战第16天】epoll 通过改进的接口设计,避免了用户态 - 内核态频繁的数据拷贝,大大提高了系统性能。在使用 epoll 的时候,我们一定要理解条件触发和边缘触发两种模式。

epoll 还是一种 I/O 多路复用技术, epoll 通过监控注册的多个描述字,来进行 I/O 事件的分发处理。不同于 poll 的是,epoll 不仅提供了默认的 level-triggered(条件触发)机制,还提供了性能更为强劲的 edge-triggered(边缘触发)机制。


使用 epoll 进行网络程序的编写,需要三个步骤,分别是 epoll_create,epoll_ctl 和 epoll_wait。

1、epoll_create

int epoll_create(int size);
int epoll_create1(int flags);
        返回值: 若成功返回一个大于0的值,表示epoll实例;若返回-1表示出错

epoll_create() 方法创建了一个 epoll 实例,从 Linux 2.6.8 开始,参数 size 被自动忽略,但是该值仍需要一个大于 0 的整数。这个 epoll 实例被用来调用 epoll_ctl 和 epoll_wait,如果这个 epoll 实例不再需要,比如服务器正常关机,需要调用 close() 方法释放 epoll 实例,这样系统内核可以回收 epoll 实例所分配使用的内核资源。


关于这个参数 size,在一开始的 epoll_create 实现中,是用来告知内核期望监控的文件描述字大小,然后内核使用这部分的信息来初始化内核数据结构,在新的实现中,这个参数不再被需要,因为内核可以动态分配需要的内核数据结构。我们只需要注意,每次将 size 设置成一个大于 0 的整数就可以了。


epoll_create1() 的用法和 epoll_create() 基本一致,如果 epoll_create1() 的输入 flags 为 0,则和 epoll_create() 一样,内核自动忽略。

2、epoll_ctl

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
        返回值: 若成功返回0;若返回-1表示出错

在创建完 epoll 实例之后,可以通过调用 epoll_ctl 往这个 epoll 实例增加或删除监控的事件。函数 epll_ctl 有 4 个入口参数。


第一个参数 epfd 是刚刚调用 epoll_create 创建的 epoll 实例描述字,可以简单理解成是 epoll 句柄。


第二个参数表示增加还是删除一个监控事件,它有三个选项可供选择:

  • EPOLL_CTL_ADD: 向 epoll 实例注册文件描述符对应的事件;
  • EPOLL_CTL_DEL:向 epoll 实例删除文件描述符对应的事件;
  • EPOLL_CTL_MOD: 修改文件描述符对应的事件。


第三个参数是注册的事件的文件描述符,比如一个监听套接字。


第四个参数表示的是注册的事件类型,并且可以在这个结构体里设置用户需要的数据,其中最为常见的是使用联合结构里的 fd 字段,表示事件所对应的文件描述符。

typedef union epoll_data {
     void        *ptr;
     int          fd;
     uint32_t     u32;
     uint64_t     u64;
 } epoll_data_t;
 struct epoll_event {
     uint32_t     events;      /* Epoll events */
     epoll_data_t data;        /* User data variable */
 };


重点看一下这几种事件类型:

  • EPOLLIN:表示对应的文件描述字可以读;
  • EPOLLOUT:表示对应的文件描述字可以写;
  • EPOLLRDHUP:表示套接字的一端已经关闭,或者半关闭;
  • EPOLLHUP:表示对应的文件描述字被挂起;
  • EPOLLET:设置为 edge-triggered,默认为 level-triggered。

3、epoll_wait

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
  返回值: 成功返回的是一个大于0的数,表示事件的个数;返回0表示的是超时时间到;若出错返回-1.

epoll_wait() 函数类似之前的 poll 和 select 函数,调用者进程被挂起,在等待内核 I/O 事件的分发。


这个函数的第一个参数是 epoll 实例描述字,也就是 epoll 句柄。


第二个参数返回给用户空间需要处理的 I/O 事件,这是一个数组,数组的大小由 epoll_wait 的返回值决定,这个数组的每个元素都是一个需要待处理的 I/O 事件,其中 events 表示具体的事件类型,

事件类型取值和 epoll_ctl 可设置的值一样,这个 epoll_event 结构体里的 data 值就是在 epoll_ctl 那里设置的 data,也就是用户空间和内核空间调用时需要的数据。


第三个参数是一个大于 0 的整数,表示 epoll_wait 可以返回的最大事件值。


第四个参数是 epoll_wait 阻塞调用的超时值,如果这个值设置为 -1,表示不超时;如果设置为 0 则立即返回,即使没有任何 I/O 事件发生。


Linux 中 epoll 的出现,为高性能网络编程补齐了最后一块拼图。epoll 通过改进的接口设计,避免了用户态 - 内核态频繁的数据拷贝,大大提高了系统性能。在使用 epoll 的时候,我们一定要理解条件触发和边缘触发两种模式。条件触发的意思是只要满足事件的条件,比如有数据需要读,就一直不断地把这个事件传递给用户;而边缘触发的意思是只有第一次满足条件的时候才触发,之后就不会再传递同样的事件了。

相关文章
|
18天前
|
存储 安全 前端开发
Web渗透-文件上传漏洞-上篇
文件上传漏洞常见于Web应用,因类型限制不严可致恶意文件执行。本文介绍前端检测、MIME类型、黑名单、.htaccess、空格、双写等多种绕过方式,并结合upload-labs靶场演示利用方法,提升安全防护认知。
87 0
Web渗透-文件上传漏洞-上篇
|
5月前
|
人工智能 运维 云计算
专家对谈|AI推动文化传媒行业向“新”发展
随着“人工智能+”行动的深入推进,文化传媒行业正经历深刻变革。云计算与AI深度融合,重构内容生产、分发全流程,为行业注入新动能。预计到2025年,我国AI核心产业规模将破万亿,文化传媒作为技术应用先锋,以两位数增速迈向智能化。在CCBN活动现场,中央广播电视总台与阿里云探讨了大模型如何驱动行业升级,展望未来新图景。汪莹指出,大模型将重构文化消费形态,助力生产力与传播力倍增,推动中国文化走向世界。同时,解决AI应用“最后一公里”问题需产业链各方协同发力,基于现有大模型能力进行二次开发是切实可行路径。
288 4
|
7月前
|
开发者
HarmonyOS NEXT 实战系列09-生命周期
页面与组件生命周期介绍:页面生命周期(@Entry装饰)包含onPageShow、onPageHide、onBackPress等接口,分别在页面显示、隐藏和返回按钮点击时触发;组件生命周期(@Component装饰)包含aboutToAppear和aboutToDisappear,在组件创建与销毁时回调。示例代码展示了生命周期函数的使用场景及执行时机,帮助开发者更好地管理页面和组件状态。
HarmonyOS NEXT 实战系列09-生命周期
|
Web App开发 缓存 JavaScript
【开发工具】【windows】Visual Studio Code(VS Code)远程Linux服务器环境搭建——SSH篇
【开发工具】【windows】Visual Studio Code(VS Code)远程Linux服务器环境搭建——SSH篇
1023 0
【开发工具】【windows】Visual Studio Code(VS Code)远程Linux服务器环境搭建——SSH篇
|
11月前
|
机器学习/深度学习 传感器 自动驾驶
基于深度学习的图像识别技术在自动驾驶领域的应用与挑战####
本文旨在探讨深度学习驱动下的图像识别技术于自动驾驶汽车中的应用现状,重点分析其在环境感知、障碍物检测及路径规划等方面的贡献,并深入剖析该技术面临的数据依赖性、算法泛化能力、实时处理需求等核心挑战。通过综述当前主流算法框架与最新研究成果,本文为推动自动驾驶技术的稳健发展提供理论参考与实践指导。 ####
308 7
|
11月前
|
敏捷开发 测试技术 持续交付
探索自动化测试:从基础到高级
【10月更文挑战第35天】在软件质量的保证过程中,自动化测试以其高效和可重复性成为不可或缺的一环。本文旨在通过简明的语言和实际案例引导读者了解自动化测试的核心概念、工具选择与应用,以及如何实现从入门到精通的过渡。我们将一起探讨如何将自动化测试策略融入日常开发流程中,提升测试效率,同时确保产品质量。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧。
178 3
|
关系型数据库 MySQL 数据库连接
win10关于mysql5.7数据库连接不上的解决方法
win10关于mysql5.7数据库连接不上的解决方法
352 0
|
编解码 监控 算法
嵌入式linux下的FFmpeg交叉编译(最全面)
嵌入式linux下的FFmpeg交叉编译(最全面)
|
关系型数据库 C语言
VT技术(二)检测CPU支持
1.CPUID指令检测 在进入VMX Opreation之前必须要检测CPU是否支持VMX技术,可以通过CPUID指令进行查询,在执行CPUID指令之后,返回值存入EAX,EBX,ECX,EDX中,查看ECX.VMX[5]位是否为1,否则不支持VMX技术,关于CPUID指令的介绍可以参考Intel白皮书卷二第三章第三节 Instruction-CPUID Identification详细介绍了CPUID的参数
720 0