linux下的各种I/O多路复用详解---select/poll/epoll

发布时间:2026/8/15 17:13:54

linux下的各种I/O多路复用详解---select/poll/epoll
多路复用技术是一种通过共享物理信道实现多路信号传输的通信技术其核心原理是利用复用器将多路信号合成单一信号传输接收端通过分用器分离还原。该技术主要包括频分复用FDM、时分复用TDM、波分复用WDM、码分多址CDMA和空分多址SDMA等类型其中FDM通过划分频段实现ADSL数据传输TDM采用时分片机制支持T1载波传输WDM通过不同波长光信号在光纤中实现双向通信。该部分来源于百度百科select的概念和原理select是一种事件通知机制通常用于阻塞式 I/O 操作中它允许程序在多个文件描述符上进行监视一旦某个文件描述符变得可读、可写或出现异常select会通知程序进行相应的处理。select会在多个文件描述符上设置监视例如读、写、异常状态然后它会阻塞程序直到以下事件之一发生读事件某个文件描述符准备好读取数据如套接字接收到数据。写事件某个文件描述符准备好写入数据如套接字可以发送数据。异常事件文件描述符处于异常状态如套接字连接关闭。select会返回发生事件的文件描述符列表程序可以通过这些文件描述符来进一步处理数据。select原型int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);nfds最大文件描述符值加1。通常可以传入所有需要监视的文件描述符的最大值加1。readfds用于监视哪些文件描述符可以读取即数据已准备好读取。writefds用于监视哪些文件描述符可以写入。exceptfds用于监视哪些文件描述符发生了异常。timeout指定等待事件的最长时间。如果为NULL则select会阻塞直到有事件发生如果设置为0则为非阻塞模式否则设置为一个timeval结构体表示的超时时间。select的使用struct timeval timeout; timeout.tv_sec 5; // 等待最多5秒 timeout.tv_usec 0; int ready select(socket_fd 1, readfds, NULL, NULL, timeout); if (ready 0) { perror(select error); } else if (ready 0) { printf(timeout\n); } else { if (FD_ISSET(socket_fd, readfds)) { // 如果 socket_fd 可读进行读取操作 char buffer[1024]; int len read(socket_fd, buffer, sizeof(buffer)); if (len 0) { printf(Received data: %s\n, buffer); } } }select的不足文件描述符数量限制select的最大文件描述符数目是由fd_set中的位数限制的通常在 1024 或 4096 左右。超出这个数量select将无法处理。因此在高并发的应用场景下select可能不够高效。性能瓶颈当需要监视大量的文件描述符时select会不断地遍历所有文件描述符检查哪些描述符有事件发生。这可能导致性能瓶颈特别是在大规模的并发连接情况下。无法支持优先级select不支持文件描述符的优先级调度因此它处理多个文件描述符时是公平的不会根据优先级处理某些请求。poll的概念和原理poll是select的一个改进版本常用于多路复用I/O多路复用的场景它允许程序监控多个文件描述符的状态如是否可以读写。poll原型#include poll.h int poll(struct pollfd *fds, nfds_t nfds, int timeout);fds一个pollfd结构体数组表示要监视的文件描述符及其关注的事件。nfds要监视的文件描述符的数量即fds数组的大小。timeout指定poll阻塞等待的时间单位是毫秒。如果为负数则阻塞直到有事件发生如果为 0则立即返回如果为正数则等待指定的时间后返回。poll的使用#include stdio.h #include stdlib.h #include unistd.h #include string.h #include sys/socket.h #include arpa/inet.h #include poll.h #define PORT 8080 int main() { int server_fd, new_socket; struct sockaddr_in address; int addr_len sizeof(address); // 创建服务器套接字 if ((server_fd socket(AF_INET, SOCK_STREAM, 0)) 0) { perror(socket failed); exit(EXIT_FAILURE); } address.sin_family AF_INET; address.sin_addr.s_addr INADDR_ANY; address.sin_port htons(PORT); // 绑定套接字 if (bind(server_fd, (struct sockaddr *)address, sizeof(address)) 0) { perror(bind failed); exit(EXIT_FAILURE); } // 监听客户端连接 if (listen(server_fd, 3) 0) { perror(listen failed); exit(EXIT_FAILURE); } // 创建 pollfd 结构体 struct pollfd fds[1]; fds[0].fd server_fd; fds[0].events POLLIN; // 关注可读事件 printf(Server is listening on port %d...\n, PORT); while (1) { // 调用 poll等待事件 int ret poll(fds, 1, -1); // -1 表示无限阻塞 if (ret 0) { perror(poll failed); exit(EXIT_FAILURE); } // 检查是否有可读事件 if (fds[0].revents POLLIN) { new_socket accept(server_fd, (struct sockaddr *)address, (socklen_t*)addr_len); if (new_socket 0) { perror(accept failed); continue; } printf(New connection established\n); // 读取数据 char buffer[1024] {0}; int valread read(new_socket, buffer, sizeof(buffer)); if (valread 0) { printf(Received message: %s\n, buffer); } close(new_socket); } } return 0; }poll的缺点和优点优点没有文件描述符数量的限制不像select限制了文件描述符数量poll可以处理更大规模的文件描述符。灵活的事件选择通过pollfd可以灵活地指定感兴趣的事件并且能够处理多种类型的事件。缺点性能瓶颈在大量文件描述符的情况下poll仍然会遍历所有文件描述符因此它在大规模并发连接时的性能较低。没有优先级poll处理事件的方式是均等的没有优先级调度功能。epoll的概念和原理epoll是 Linux 下提供的高效的 I/O 多路复用机制特别适用于处理大量并发连接。与select和poll相比epoll提供了更高效的方式来管理大量文件描述符。epoll相关函数epoll_create创建一个 epoll 实例返回一个文件描述符。 int epoll_create(int size); size 参数已被废弃但它仍然被要求传递。通常传入一个大于零的数。 epoll_ctl用于添加、删除或修改事件。 int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); epfdepoll_create 返回的 epoll 文件描述符。 op操作类型EPOLL_CTL_ADD、EPOLL_CTL_DEL、EPOLL_CTL_MOD。 fd待操作的文件描述符。 event待监控的事件结构。 epoll_wait等待事件发生并返回就绪的文件描述符。 int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout); epfdepoll_create 返回的 epoll 文件描述符。 events用于存放就绪事件的数组。 maxevents数组大小。 timeout等待时间单位毫秒可以设置为 -1永久阻塞0非阻塞或正数指定超时时间。epoll的使用#include stdio.h #include stdlib.h #include unistd.h #include string.h #include sys/socket.h #include arpa/inet.h #include sys/epoll.h #define PORT 8080 #define MAX_EVENTS 10 int main() { int server_fd, client_fd, epfd, n; struct sockaddr_in address; struct epoll_event ev, events[MAX_EVENTS]; int addr_len sizeof(address); // 创建服务器套接字 if ((server_fd socket(AF_INET, SOCK_STREAM, 0)) 0) { perror(socket failed); exit(EXIT_FAILURE); } address.sin_family AF_INET; address.sin_addr.s_addr INADDR_ANY; address.sin_port htons(PORT); // 绑定套接字 if (bind(server_fd, (struct sockaddr *)address, sizeof(address)) 0) { perror(bind failed); exit(EXIT_FAILURE); } // 监听客户端连接 if (listen(server_fd, 3) 0) { perror(listen failed); exit(EXIT_FAILURE); } // 创建 epoll 实例 epfd epoll_create1(0); if (epfd -1) { perror(epoll_create failed); exit(EXIT_FAILURE); } // 将 server_fd 添加到 epoll 监控列表中 ev.events EPOLLIN; ev.data.fd server_fd; if (epoll_ctl(epfd, EPOLL_CTL_ADD, server_fd, ev) -1) { perror(epoll_ctl failed); exit(EXIT_FAILURE); } printf(Server is listening on port %d...\n, PORT); while (1) { // 等待事件发生 n epoll_wait(epfd, events, MAX_EVENTS, -1); if (n -1) { perror(epoll_wait failed); exit(EXIT_FAILURE); } // 处理所有就绪事件 for (int i 0; i n; i) { if (events[i].data.fd server_fd) { // 新连接到达 client_fd accept(server_fd, (struct sockaddr *)address, (socklen_t*)addr_len); if (client_fd -1) { perror(accept failed); continue; } // 将 client_fd 添加到 epoll 监控列表中 ev.events EPOLLIN; ev.data.fd client_fd; if (epoll_ctl(epfd, EPOLL_CTL_ADD, client_fd, ev) -1) { perror(epoll_ctl failed); exit(EXIT_FAILURE); } printf(New connection established\n); } else if (events[i].events EPOLLIN) { // 有数据可读 char buffer[1024] {0}; int len read(events[i].data.fd, buffer, sizeof(buffer)); if (len 0) { printf(Received: %s\n, buffer); } else { // 客户端关闭连接 printf(Closing connection\n); close(events[i].data.fd); } } } } close(server_fd); close(epfd); return 0; }epoll的优点高效性epoll使用事件驱动模式当有文件描述符就绪时才通知应用程序因此避免了poll和select中每次都要遍历所有文件描述符的性能问题。支持大规模并发在大量并发连接的情况下epoll处理效率更高尤其是当活跃的文件描述符很少时它只会通知那些就绪的文件描述符避免了不必要的检查。支持边缘触发和水平触发epoll提供了两种触发模式可以根据需要选择。总结特性selectpollepoll最大文件描述符限制通常 1024没有最大文件描述符限制没有文件描述符数量的限制效率随着文件描述符增加性能下降随着文件描述符增加性能下降高效性能不随文件描述符数量变化API设计每次调用时需要重设文件描述符使用结构体数组使用事件驱动灵活且高效操作方式阻塞或非阻塞阻塞或非阻塞阻塞、非阻塞、事件驱动适用场景文件描述符数量较少简单应用文件描述符数量适中但不高高并发场景如大规模网络服务优点简单易用较灵活解决了 select 限制极高的性能无限制的并发处理

相关新闻

三步搭好第一套Build:Path of Building离线规划工具新手实操指南

三步搭好第一套Build:Path of Building离线规划工具新手实操指南

2026/8/15 17:03:54

三步搭好第一套Build:Path of Building离线规划工具新手实操指南 【免费下载链接】PathOfBuilding Offline build planner for Path of Exile. 项目地址: https://gitcode.com/GitHub_Trending/pa/PathOfBuilding 周末晚上,朋友在群里甩来一条消息…

为什么说Ghidra 12.2是最值得升级的一版逆向分析框架:调试器不崩、脚本好写、比对更快

为什么说Ghidra 12.2是最值得升级的一版逆向分析框架:调试器不崩、脚本好写、比对更快

2026/8/15 17:03:54

为什么说Ghidra 12.2是最值得升级的一版逆向分析框架:调试器不崩、脚本好写、比对更快 【免费下载链接】ghidra Ghidra is a software reverse engineering (SRE) framework 项目地址: https://gitcode.com/GitHub_Trending/gh/ghidra 如果你靠Ghidra逆向分析…

轻松计算电感上的三角波电流

轻松计算电感上的三角波电流

2026/8/15 17:03:54

在开关电源的计算中,往往涉及到三角波电流(DCM模式)的计算,本内容详细的介绍其平均电流Iavg、均方根RMS以及交流分量的计算。CCM模式的计算移步:轻松计算电感上的梯形波电流。 充分地理解公式远不止于记住它的形式和计算结果。真正的要义在于…

Welcome UI性能优化:提升React应用加载速度的7个实用技巧

Welcome UI性能优化:提升React应用加载速度的7个实用技巧

2026/8/15 20:44:03

Welcome UI性能优化:提升React应用加载速度的7个实用技巧 【免费下载链接】welcome-ui Customizable design system from Welcome to the jungle (wttj) with react, typescript, tailwindcss, ariakit and a lot of love 💛 Here youll find all the co…

流放之路Build规划从翻车到上岸:Path of Building保姆级实战,这5个坑你别踩

流放之路Build规划从翻车到上岸:Path of Building保姆级实战,这5个坑你别踩

2026/8/15 20:44:03

流放之路Build规划从翻车到上岸:Path of Building保姆级实战,这5个坑你别踩 【免费下载链接】PathOfBuilding Offline build planner for Path of Exile. 项目地址: https://gitcode.com/GitHub_Trending/pa/PathOfBuilding 赛季开服第三周&#…

解决arduino-esp32fs-plugin常见问题:上传失败、分区错误等终极方案

解决arduino-esp32fs-plugin常见问题:上传失败、分区错误等终极方案

2026/8/15 20:44:03

解决arduino-esp32fs-plugin常见问题:上传失败、分区错误等终极方案 【免费下载链接】arduino-esp32fs-plugin Arduino plugin for uploading files to ESP32 file system 项目地址: https://gitcode.com/gh_mirrors/ar/arduino-esp32fs-plugin arduino-esp3…

ESS高级特性详解:代码补全、语法高亮与自动缩进全攻略

ESS高级特性详解:代码补全、语法高亮与自动缩进全攻略

2026/8/15 20:44:03

ESS高级特性详解:代码补全、语法高亮与自动缩进全攻略 【免费下载链接】ESS Emacs Speaks Statistics: ESS 项目地址: https://gitcode.com/gh_mirrors/ess1/ESS ESS(Emacs Speaks Statistics)是一款专为统计编程语言打造的Emacs扩展包…

优必选超仿生机器人:当“像人”不再是终极目标,我们究竟在追求什么?

优必选超仿生机器人:当“像人”不再是终极目标,我们究竟在追求什么?

2026/8/15 20:44:03

🌊 专注 AI 大模型与前沿科技深度解析,习惯从工程师视角拆解技术热点,让我们一起在技术浪潮中保持清醒与好奇 🚀优必选超仿生机器人:当“像人”不再是终极目标,我们究竟在追求什么? 清晨七点&am…

让文档自己长出知识库:我用 WeKnora 把散落资料变成会答题的智能助手指南

让文档自己长出知识库:我用 WeKnora 把散落资料变成会答题的智能助手指南

2026/8/15 20:34:02

让文档自己长出知识库:我用 WeKnora 把散落资料变成会答题的智能助手指南 【免费下载链接】WeKnora Open-source LLM knowledge platform: turn raw documents into a queryable RAG, an autonomous reasoning agent, and a self-maintaining Wiki. 项目地址: htt…

比较好的亚太EMBA,问了6位校友师资差别真的挺大

比较好的亚太EMBA,问了6位校友师资差别真的挺大

2026/8/13 11:01:28

比较好的亚太EMBA核心差异先看什么?对于希望兼顾工作与系统管理能力提升的亚太区高管而言,筛选匹配度高的EMBA项目时,师资配置是决定学习体验与实际收获的核心要素之一。我们结合3-4个公开信息透明、办学历史较长的亚太区主流EMBA项目特点&am…

备考3个月对比6份资料 海外游学的亚洲EMBA面试注意点

备考3个月对比6份资料 海外游学的亚洲EMBA面试注意点

2026/8/14 10:48:24

备考海外游学的亚洲EMBA面试,核心要围绕项目国际化设计逻辑、个人跨文化管理经验匹配度两个维度准备,避免把游学模块等同于普通旅游参访的认知偏差。不少备考者花3个月对比6份资料,却容易忽略面试官对“国际视野落地能力”的考察——比如香港…

比较好的国内EMBA,问了二十位校友聊透人脉价值

比较好的国内EMBA,问了二十位校友聊透人脉价值

2026/8/13 17:17:06

比较好的国内EMBA核心差异体现在哪些方面?比较好的国内EMBA的核心长期价值,很大程度上依托于校友网络的连接质量与资源生态的活跃度,这也是不少高管在择校时优先考量的因素。我们结合3-4个市场关注度较高的项目公开信息,从课程、师…

一文读懂快消WMS怎么选?2026年国内外10大主流WMS品牌盘点

一文读懂快消WMS怎么选?2026年国内外10大主流WMS品牌盘点

2026/8/15 0:03:07

快消品(FMCG)是流通速度较快、竞争较为激烈的行业之一。一瓶饮料从出厂到消费者手中,往往只有几十天甚至几天的周转窗口。这决定了快消行业的仓储管理系统(WMS)与制造业、电商行业存在明显区别:它不仅需要管…

内景 空间站内部 中国空间站 太空 内仓

内景 空间站内部 中国空间站 太空 内仓

2026/8/15 0:03:07

本项目为前几天收费帮学妹做的一个项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。 一、项目描述 空间站内部 中国空间站 太空 内仓 地址:本地PC端运行(或Web…

重新定义数据接口:3个突破性场景让通达信数据读取更智能

重新定义数据接口:3个突破性场景让通达信数据读取更智能

2026/8/15 0:03:07

重新定义数据接口:3个突破性场景让通达信数据读取更智能 【免费下载链接】mootdx 通达信数据读取的一个简便使用封装 项目地址: https://gitcode.com/GitHub_Trending/mo/mootdx 当我们面对海量金融数据时,传统的数据获取方式往往让我们陷入困境—…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/15 1:04:46

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/15 10:10:27

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/14 19:35:14

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…