Linux I/O多路复用:深入浅出poll与epoll
一、poll系统调用poll是System V引入的I/O多路复用函数它克服了select的一些限制如文件描述符数量上限。poll通过一个结构体数组来监视多个文件描述符的事件。1. 函数原型#include poll.h int poll(struct pollfd *fds, nfds_t nfds, int timeout);参数fds指向struct pollfd数组的指针每个元素描述一个待监视的文件描述符及其感兴趣的事件。nfdsfds数组中的元素个数。timeout超时时间毫秒。-1阻塞直到有事件发生0立即返回不阻塞0等待指定的毫秒数。返回值成功返回就绪有事件发生的文件描述符个数。超时返回0。出错返回-1并设置errno。struct pollfd定义如下struct pollfd { int fd; /* 文件描述符 */ short events; /* 等待的事件掩码 */ short revents; /* 实际发生的事件掩码 */ };events和revents是由以下标志按位或组成的位掩码POLLIN有数据可读。POLLOUT可写数据。POLLERR发生错误仅输出。POLLHUP挂起仅输出。等等。2. 使用示例struct pollfd fds[2]; fds[0].fd sockfd; fds[0].events POLLIN; fds[1].fd STDIN_FILENO; fds[1].events POLLIN; int ret poll(fds, 2, 5000); // 等待5秒 if (ret 0) { for (int i 0; i 2; i) { if (fds[i].revents POLLIN) { // 处理该文件描述符的读事件 } } } else if (ret 0) { // 超时处理 } else { perror(poll); }3. poll的特点与局限性优点没有最大文件描述符数量的限制基于链表存储受系统内存约束。接口相对简单支持多种事件类型。缺点每次调用都需要将pollfd数组从用户态拷贝到内核态当监视大量文件描述符时开销较大。内核检测到事件后仍需遍历整个数组以查找哪些描述符就绪线性扫描时间复杂度O(n)。无法动态修改监视的描述符集合需要重新组织数组并调用poll。只能工作在水平触发模式Level-Triggered, LT即只要文件描述符处于就绪状态每次poll都会报告该事件。二、epollLinux特有的高性能I/O事件通知机制epoll是Linux内核为处理大批量文件描述符而引入的增强版I/O多路复用接口它解决了poll和select的性能瓶颈。epoll通过内核事件表、回调机制和内存映射等技术实现了高效的I/O事件通知。1. 核心函数epoll提供三个系统调用(1)epoll_create#include sys/epoll.h int epoll_create(int size);功能创建一个epoll实例返回一个指向内核事件表的文件描述符称为epfd。参数size提示内核事件表的大小Linux 2.6.8之后被忽略但必须大于0。返回值成功返回新的文件描述符失败返回-1。(2)epoll_ctlint epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);功能对内核事件表进行控制添加、修改或删除一个监视的文件描述符。参数epfdepoll实例的文件描述符。op操作类型可取EPOLL_CTL_ADD添加fd到事件表。EPOLL_CTL_MOD修改fd上已注册的事件。EPOLL_CTL_DEL从事件表中删除fd。fd要操作的文件描述符。event指向struct epoll_event的指针描述感兴趣的事件和用户数据。struct epoll_event定义如下typedef union epoll_data { void *ptr; int fd; uint32_t u32; uint64_t u64; } epoll_data_t; struct epoll_event { uint32_t events; /* 感兴趣的事件掩码 */ epoll_data_t data; /* 用户数据 */ };events可以是以下宏的按位或EPOLLIN可读。EPOLLOUT可写。EPOLLRDHUP流套接字对端关闭连接。EPOLLPRI有紧急数据可读。EPOLLERR发生错误自动设置无需手动注册。EPOLLHUP挂起自动设置。EPOLLET设置为边缘触发模式Edge-Triggered, ET。EPOLLONESHOT事件只触发一次触发后需要重新注册。(3)epoll_waitint epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);功能等待事件表中的文件描述符产生事件。参数epfdepoll实例的文件描述符。events用户提供的数组用于存放内核返回的就绪事件。maxeventsevents数组的大小即最多返回多少个事件。timeout超时时间毫秒语义与poll相同。返回值成功返回就绪事件个数超时返回0失败返回-1。2. 使用示例服务器监听socketint epfd epoll_create(1); struct epoll_event ev, events[10]; ev.events EPOLLIN; ev.data.fd listen_sock; epoll_ctl(epfd, EPOLL_CTL_ADD, listen_sock, ev); while (1) { int nfds epoll_wait(epfd, events, 10, -1); for (int i 0; i nfds; i) { if (events[i].data.fd listen_sock) { // 处理新连接 int conn accept(listen_sock, ...); ev.events EPOLLIN | EPOLLET; // 边缘触发 ev.data.fd conn; epoll_ctl(epfd, EPOLL_CTL_ADD, conn, ev); } else { // 处理已连接套接字的读写 } } }3. epoll的工作模式水平触发与边缘触发水平触发LTLevel-Triggered默认模式。当文件描述符就绪时epoll_wait会返回该事件如果程序没有一次性处理完所有数据下一次调用epoll_wait会再次报告该事件直到数据被处理完。这种模式编程简单不容易遗漏事件但可能重复触发。边缘触发ETEdge-Triggered需要设置EPOLLET标志。当文件描述符从未就绪变为就绪时epoll_wait仅返回一次该事件。如果程序没有处理完所有数据后续不再通知除非描述符再次出现新的状态变化。ET模式要求程序员必须一次性将数据全部读取或写入通常使用非阻塞I/O循环处理否则可能造成数据丢失或饥饿。ET模式效率更高减少了epoll的重复触发次数但编程复杂度较高。4. epoll的优势无文件描述符数量上限epoll监视的描述符数量只受系统内存限制。事件驱动避免线性扫描内核通过回调机制将就绪的描述符加入就绪队列epoll_wait直接返回就绪队列时间复杂度O(1)仅返回就绪个数。内存映射减少拷贝epoll使用mmap在内核和用户空间共享事件表避免了用户态到内核态的数据拷贝事件注册时仍需拷贝但相比poll的每次全量拷贝要少。支持边缘触发在高并发场景下可进一步减少系统调用次数。可修改监视事件通过epoll_ctl动态添加、删除、修改监视的描述符无需重新构建整个集合。三、select、poll、epoll对比总结特性selectpollepoll底层数据结构位数组fd_setpollfd数组链表红黑树就绪链表最大连接数有限通常1024无上限受内存限制无上限受内存限制事件集合拷贝每次调用都从用户态拷贝到内核态每次调用都从用户态拷贝到内核态使用epoll_ctl注册通过mmap共享减少拷贝查找就绪描述符方式线性遍历所有fd线性遍历所有fd直接返回就绪队列无需遍历工作模式仅LT仅LT支持LT和ET修改监视集需要重新构造fd_set并重调select需要重新组织pollfd数组并重调poll使用epoll_ctl动态增删改无需重建时间复杂度获取就绪fdO(n)O(n)O(1)就绪个数可移植性广泛支持POSIX广泛支持POSIXLinux特有四、适用场景建议select适用于连接数较少1024且对可移植性要求高的场景代码简单。poll相比select没有最大连接数限制但仍有线性遍历开销适合中等规模的连接数几千以内。epoll高并发服务器如C10K问题的首选尤其是当连接数巨大且活动连接比例较低时ET模式能最大化性能。但需注意epoll是Linux专属跨平台需考虑替代方案如libevent、libuv等封装库。

相关新闻

Web前端性能优化:伏羲气象数据大屏的流畅体验之道

Web前端性能优化:伏羲气象数据大屏的流畅体验之道

Web前端性能优化:伏羲气象数据大屏的流畅体验之道 最近在做一个挺有意思的项目,一个展示伏羲气象模型预报结果的Web数据大屏。这东西听起来酷,做起来可真是挑战不小。想象一下,屏幕上要实时展示全球范围、多层级的网格化气象数据…

2026/7/4 14:34:38 阅读更多 →
探秘:全国TOP5性价比超高的变压器生产厂,你知道几家?

探秘:全国TOP5性价比超高的变压器生产厂,你知道几家?

大家好,我是你们的老朋友小张。今天咱们聊聊一个看似离我们很远,但其实与我们生活息息相关的话题——变压器。变压器作为电力系统的核心设备,它的性能和价格直接影响到我们的用电体验。今天,我就带大家探秘全国TOP5性价比超高的变…

2026/7/4 14:34:32 阅读更多 →
YOLOv13模型训练全流程:使用官版镜像自定义数据集实战

YOLOv13模型训练全流程:使用官版镜像自定义数据集实战

YOLOv13模型训练全流程:使用官版镜像自定义数据集实战 1. 引言:从零开始,用你自己的数据训练一个检测模型 如果你对目标检测感兴趣,或者正在寻找一个能快速上手、效果又好的模型来识别你关心的特定物体,那么你来对地…

2026/5/17 0:53:11 阅读更多 →

最新新闻

Hugging Face Hub大文件上传实战指南

Hugging Face Hub大文件上传实战指南

1. 大文件上传需求背景在机器学习领域,数据集和模型文件往往体积庞大。以常见的计算机视觉数据集为例,一个中等规模的图像数据集可能达到几十GB甚至上百GB。传统的文件托管服务要么有严格的容量限制,要么缺乏版本控制功能,给团队协…

2026/7/4 14:34:07 阅读更多 →
如何用C开发的开源CAD软件LitCAD,15分钟开启你的专业绘图之旅?

如何用C开发的开源CAD软件LitCAD,15分钟开启你的专业绘图之旅?

如何用C#开发的开源CAD软件LitCAD,15分钟开启你的专业绘图之旅? 【免费下载链接】LitCAD A very simple CAD developed by C#. 项目地址: https://gitcode.com/gh_mirrors/li/LitCAD 你是否曾因专业CAD软件的复杂界面和高昂费用而望而却步&#x…

2026/7/4 14:34:07 阅读更多 →
AutoRaise:彻底改变macOS窗口管理的鼠标悬停自动聚焦神器

AutoRaise:彻底改变macOS窗口管理的鼠标悬停自动聚焦神器

AutoRaise:彻底改变macOS窗口管理的鼠标悬停自动聚焦神器 【免费下载链接】AutoRaise AutoRaise (and focus) a window when hovering over it with the mouse 项目地址: https://gitcode.com/gh_mirrors/au/AutoRaise 你是否厌倦了在多个窗口间频繁点击切换…

2026/7/4 14:32:06 阅读更多 →
Lemos零代码构建智能知识图谱

Lemos零代码构建智能知识图谱

Lemos智能图谱知识库与免费且可本地部署的知识库(如部分开源Wiki、笔记软件)的核心区别在于其底层架构从“静态文档库”升级为“AI驱动的动态知识网络”,这带来了在知识组织、处理、应用及协作层面的系统性优势。 对比维度免费/本地部署的传…

2026/7/4 14:32:06 阅读更多 →
LV30条码扫描器与PIC18F86J11微控制器集成方案

LV30条码扫描器与PIC18F86J11微控制器集成方案

1. LV30条码扫描器与PIC18F86J11微控制器的技术背景 LV30是一款工业级线性影像式条码扫描引擎,采用先进的CMOS图像传感器技术,能够以每秒1000次扫描的频率捕获条码图像。与传统的激光扫描器相比,它的核心优势在于能够处理各种特殊介质上的条码…

2026/7/4 14:30:05 阅读更多 →
基于HSV颜色空间的人民币面值自动识别系统开发

基于HSV颜色空间的人民币面值自动识别系统开发

1. 项目概述 人民币面值自动识别系统是一个典型的数字图像处理应用场景。我在实际开发中发现,相比传统OCR技术,基于RGB颜色分量的识别方法在特定场景下具有独特优势。这种方法不依赖复杂的字符识别算法,而是通过分析纸币的主色调特征来实现快…

2026/7/4 14:30:05 阅读更多 →

日新闻

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 正式发布,这是一个关键的安全修复版本,修复了多个方面的问题,还对部分功能进行了优化。 安全修复亮点 此次发布在安全修复上表现突出。binprot 避免了项目引用计数溢出,mcmc 因安全问题提升了上游版本号&#xf…

2026/7/4 0:04:29 阅读更多 →
终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案 【免费下载链接】HMCL A Minecraft Launcher which is multi-functional, cross-platform and popular 项目地址: https://gitcode.com/gh_mirrors/hm/HMCL HMCL(Hello Minecraft! Lau…

2026/7/4 0:06:29 阅读更多 →
KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

1. KMX63与PIC18F66K40的硬件协同架构解析KMX63作为一款三轴加速度计和磁力计组合传感器,与PIC18F66K40微控制器的搭配堪称嵌入式HMI开发的黄金组合。这套硬件组合的核心优势在于KMX63提供的高精度运动感知能力与PIC18F66K40强大的信号处理能力形成了完美互补。KMX6…

2026/7/4 0:06:29 阅读更多 →

周新闻

月新闻