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 限制极高的性能无限制的并发处理

相关新闻

一次虚拟机翻车引发的思考:不用 Mac 也能从 Apple 服务器下载 macOS

一次虚拟机翻车引发的思考:不用 Mac 也能从 Apple 服务器下载 macOS

一次虚拟机翻车引发的思考:不用 Mac 也能从 Apple 服务器下载 macOS 【免费下载链接】gibMacOS Py2/py3 script that can download macOS components direct from Apple 项目地址: https://gitcode.com/gh_mirrors/gi/gibMacOS 周五晚上十一点,我…

2026/8/16 20:17:13 阅读更多 →
atc-react与MITRE ATTCK集成指南:提升威胁狩猎效率的终极技巧

atc-react与MITRE ATTCK集成指南:提升威胁狩猎效率的终极技巧

atc-react与MITRE ATT&CK集成指南:提升威胁狩猎效率的终极技巧 【免费下载链接】atc-react A knowledge base of actionable Incident Response techniques 项目地址: https://gitcode.com/gh_mirrors/at/atc-react atc-react作为一个专注于事件响应技术…

2026/8/16 19:59:19 阅读更多 →
免费法线贴图生成工具实战:拖一张灰度图,三步做出专业级凹凸质感

免费法线贴图生成工具实战:拖一张灰度图,三步做出专业级凹凸质感

免费法线贴图生成工具实战:拖一张灰度图,三步做出专业级凹凸质感 【免费下载链接】NormalMap-Online NormalMap Generator Online 项目地址: https://gitcode.com/gh_mirrors/no/NormalMap-Online 晚上十点,你盯着游戏场景里那块光秃秃…

2026/8/16 21:27:25 阅读更多 →

最新新闻

戈壁徒步需要准备什么?第一次参加前,这些问题比买装备更重要

戈壁徒步需要准备什么?第一次参加前,这些问题比买装备更重要

第一次准备戈壁徒步,很多人的动作几乎一样:先搜鞋,再看冲锋衣、登山杖、背包,最后列出一张越来越长的装备清单。社交平台上关于“戈壁徒步穿什么”“第一次徒步买什么鞋”的内容也很多,久而久之,很容易让人…

2026/8/16 23:23:47 阅读更多 →
Linux进程前后台切换:从Ctrl+Z到nohup的终端多任务管理实战

Linux进程前后台切换:从Ctrl+Z到nohup的终端多任务管理实战

1. 项目概述:为什么我们需要掌握前台后台切换?如果你在Linux终端里跑过一个需要长时间运行的程序,比如编译一个大型项目、下载一个大文件,或者启动一个Web服务,然后发现终端被“卡住”了,除了干等什么也做不…

2026/8/16 23:23:47 阅读更多 →
Windows守护进程实战:从计划任务到原生服务的三种实现方案

Windows守护进程实战:从计划任务到原生服务的三种实现方案

1. 项目概述:为什么你需要一个Windows守护进程? 在Windows世界里,我们经常遇到一些需要“默默无闻、长期坚守”的任务。比如,你需要一个程序7x24小时不间断地监控某个文件夹,一旦有新文件就自动处理;或者&a…

2026/8/16 23:23:47 阅读更多 →
Ubuntu/Linux命令行核心技能:从基础操作到高效运维实战指南

Ubuntu/Linux命令行核心技能:从基础操作到高效运维实战指南

1. 项目概述:为什么我们需要掌握Ubuntu命令?如果你刚接触Ubuntu,或者从Windows/macOS转过来,面对那个黑漆漆的终端窗口,心里可能会有点发怵。我刚开始用Ubuntu那会儿也是,总觉得用鼠标点点图形界面更踏实。…

2026/8/16 23:23:47 阅读更多 →
网络单向ping不通的五大原因与系统化排查实战指南

网络单向ping不通的五大原因与系统化排查实战指南

1. 问题现象与初步排查思路“单向能ping通”这个现象,在运维和网络排障中堪称一个经典的“幽灵问题”。你从A点ping B点,一切正常,数据包往返顺畅;但当你满怀信心地从B点ping回A点时,屏幕上却只留下一串冰冷的“请求超…

2026/8/16 23:23:47 阅读更多 →
shuohao-skills:把一本小说变成短剧拍片的素材

shuohao-skills:把一本小说变成短剧拍片的素材

丢进一本小说,AI Agent 自动拆角色、排大纲、出场景道具设定图——这个仓库让"写小说"和"拍短剧"之间只差一个 git clone 的距离。 这个项目解决什么问题? 2026 年 8 月,shuohao-skills 在 GitHub 上一周涨到 900 Star。…

2026/8/16 23:22:46 阅读更多 →

日新闻

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

如果你是一名开发者,最近可能已经感受到了AI大模型正在从“玩具”变成“生产力工具”的强烈信号。从代码补全到智能Agent,从本地部署到云端API,我们正处在一个技术栈快速重构的节点。然而,面对层出不穷的模型、框架和工具&#xf…

2026/8/16 0:00:54 阅读更多 →
工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

第四篇:反射——高频能量撞墙之后会发生什么? —— 你以为信号已经过去了,其实它正在回来打你 老Q的现场笔记 第五季,我们正式进入工业神经系统层。这里不再是单个设备的战斗,而是整个工厂“经脉”层面的秩序之战。从这一篇开始,你将第一次看清:看似简单的信号传播,背…

2026/8/16 0:00:55 阅读更多 →
【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

2026/8/16 0:03:55 阅读更多 →

周新闻

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

基于阿里云与通义千问(Qwen)构建AI应用:从模型调用到生产部署的完整实践指南

如果你是一名开发者,最近可能已经感受到了AI大模型正在从“玩具”变成“生产力工具”的强烈信号。从代码补全到智能Agent,从本地部署到云端API,我们正处在一个技术栈快速重构的节点。然而,面对层出不穷的模型、框架和工具&#xf…

2026/8/16 0:00:54 阅读更多 →
工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

工业通信系统底层逻辑:04 反射——高频能量撞墙之后会发生什么?

第四篇:反射——高频能量撞墙之后会发生什么? —— 你以为信号已经过去了,其实它正在回来打你 老Q的现场笔记 第五季,我们正式进入工业神经系统层。这里不再是单个设备的战斗,而是整个工厂“经脉”层面的秩序之战。从这一篇开始,你将第一次看清:看似简单的信号传播,背…

2026/8/16 0:00:55 阅读更多 →
【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

【文章复现】非线性值迭代自适应动态规划(ADP):离散时间非线性系统的策略迭代自适应动态规划算法研究附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和…

2026/8/16 0:03:55 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/16 6:00:23 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/16 6:00:24 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/16 6:00:27 阅读更多 →