网络编程卡壳?五种IO模型+select/poll一篇讲透,搞懂网络编程核心,阻塞/多路复用不再懵!
文章目录本篇摘要一· 五种IO模型介绍**1. 阻塞IOBlocking IO, BIO****2. 非阻塞IONon-blocking IO, NIO****3. IO多路复用Multiplexed IO****4. 信号驱动IOSignal Driven IO, SIGIO****5. 异步IOAsynchronous IO, AIO**相关概念认识同步通信 vs 异步通信阻塞 vs 非阻塞对比**一句话总结**其他高级IO拓展了解小结二.非阻塞IO之fcntlfcntl 函数基本信息fcntl 函数的 5 种主要功能**通过 fcntl 设置非阻塞模式**基于fcntl函数简单测试测试思路效果展示源码展示三. 多路转接之selectselect相关函数介绍select代码编写测试基于tcp实现echo回显设计思路测试效果源码汇总**select缺点**四.多路转接之pollpoll相关函数介绍**函数原型****核心参数****返回值****核心事件宏events/revents****使用步骤**操作流程poll代码编写测试基于tcp实现echo回显设计思路测试效果源码汇总**特点与适用场景**poll的优点poll的缺点font color#DC3545 size5 face楷体 **典型场景相比epoll落后****与 select 的对比**五.本篇小结本篇摘要本篇将介绍五种IO模型以及对其中多路转接IO的selectpoll进行介绍使用总结等。一· 五种IO模型介绍1. 阻塞IOBlocking IO, BIO核心特点应用程序发起IO操作如读/写后线程会被“卡住”直到IO完成数据到达/发送完毕。工作流程总结简单但低效适合单连接、低并发场景如早期客户端程序所有套接字默认都是阻塞IO。2. 非阻塞IONon-blocking IO, NIO核心特点应用程序发起IO操作后函数立即返回不会阻塞线程但需主动轮询检查数据是否就绪非阻塞IO:如果内核还未将数据准备好,系统调用仍然会直接返回并且返叵EWOULDBLOCK错误码。工作流程总结避免线程阻塞但需频繁轮询浪费CPU适合短连接或对延迟敏感的场景。3. IO多路复用Multiplexed IO核心特点通过一个系统调用监控多个文件描述符FD当任意一个FD就绪数据可读/写时内核通知应用程序处理。代表实现select老、poll改进、epoll高性能Linux专属。工作流程总结用“单线程管多个连接”大幅提升并发能力如Nginx、Redis用epoll。4. 信号驱动IOSignal Driven IO, SIGIO核心特点应用程序通过信号Signal通知内核“监控某个FD”当数据就绪时内核发送信号触发应用程序处理。工作流程总结异步通知但信号可能丢失或延迟实际应用较少仅适合特定场景。5. 异步IOAsynchronous IO, AIO核心特点应用程序发起IO操作后内核全程完成数据拷贝完成后主动通知应用程序无需线程干预。工作流程总结完全异步“发起即忘”效率最高适合高并发、大文件传输等场景如Windows的IOCP。因此对应信号驱动IO以及异步IO区别信号驱动是数据准备好了告诉用户自己调用接口从内核态拷贝到用户态而异步是直接让内核拿到数据后拷贝到用户态完成才进行通知用户。相关概念认识同步通信 vs 异步通信核心区别同步调用者自己发起IO操作全程等待结果返回自己干完才停。异步调用者委托他人执行IO操作完成后收到通知交给别人干自己等通知。本质差异同步IO操作由调用方“亲自执行”需阻塞等待。异步IO操作由其他组件执行调用方仅接收结果通知。阻塞 vs 非阻塞关注点程序在“等待调用结果时的状态”。区别阻塞等待期间当前线程被“挂起”卡住不动直到结果返回才能继续。非阻塞等待期间线程不被“卡住”可继续执行其他任务不干等。对比同步/异步描述“IO操作由谁执行”自己干 vs 别人干。阻塞/非阻塞描述“等待时线程是否被挂起”卡住 vs 不卡住。二者独立同步操作可能阻塞或非阻塞如同步非阻塞需轮询异步操作通常搭配非阻塞避免卡死。一句话总结从“干等”阻塞到“轮询”非阻塞再到“监控多个”多路复用最后到“内核代劳”异步IO模型逐步解决“线程效率”和“并发能力”的矛盾。其他高级IO拓展了解非阻塞 IO调用时不阻塞线程立即返回结果可能未完成需主动轮询或配合其他机制如 I/O 多路复用获取最终结果。记录锁文件锁对文件/数据加锁确保多进程/线程并发访问时的数据一致性如防止同时写入。系统 V 流机制STREAMSUNIX 系统中的一种设备驱动模型支持数据的异步处理和模块化组件现代应用较少可简单理解为“流式数据处理框架”。I/O 多路转接I/O Multiplexing通过select/poll/epoll等机制单个线程监控多个文件描述符的 IO 状态有事件时才触发处理避免轮询浪费资源常用于高并发服务端。readv/writev 函数分散/聚集 I/O允许一次系统调用读写多个内存缓冲区分散写入、聚集读取减少多次拷贝开销提高大块数据传输效率。存储映射 IOmmap将文件直接映射到进程内存空间通过内存操作访问文件避免频繁读写系统调用适合大文件随机访问和进程间共享内存。小结这些高级 IO 主要解决效率、并发控制、资源利用问题常结合使用如epoll 非阻塞 IO mmap适用于高并发、高性能场景。二.非阻塞IO之fcntlfcntl函数基本信息头文件包含unistd.h和fcntl.h函数原型intfcntl(intfd,intcmd,.../* arg */);核心功能通过不同的cmd参数实现对文件描述符的多种控制操作。fcntl函数的 5 种主要功能复制文件描述符cmdF_DUPFD复制已有描述符。获取/设置文件描述符标记cmdF_GETFD或F_SETFD操作描述符的标志如关闭标志FD_CLOEXEC。获取/设置文件状态标记cmdF_GETFL或F_SETFL控制文件读写模式如阻塞/非阻塞。获取/设置异步 I/O 所有权cmdF_GETOWN或F_SETOWN指定接收异步 I/O 信号的进程。获取/设置记录锁cmdF_GETLK、F_SETLK或F_SETLKW对文件区域加锁/解锁。通过fcntl设置非阻塞模式核心步骤以F_SETFL为例使用F_GETFL获取当前文件状态标志返回一个位图。通过按位或运算|添加O_NONBLOCK标志。使用F_SETFL将修改后的标志写回文件描述符。示例set_nonblock函数voidset_nonblock(intfd){intflagsfcntl(fd,F_GETFL,0);// 获取当前标志flags|O_NONBLOCK;// 添加非阻塞标志fcntl(fd,F_SETFL,flags);// 设置回文件描述符}基于fcntl函数简单测试测试思路将标准输入键盘设置为非阻塞模式通过无限循环持续尝试读取输入有数据时输出内容无数据时因EAGAIN/EWOULDBLOCK提示“没有数据”并休眠1秒若被信号中断EINTR则提示后继续循环其他错误则提示错误最终实现非阻塞读取标准输入的功能。效果展示标准输入流没输入就打印没有数据否则打印输入的数据。源码展示#includeiostream#includeunistd.h#includefcntl.husingstd::cout;usingstd::endl;voidset_nonblock(intfd){intflagsfcntl(fd,F_GETFL,0);flags|O_NONBLOCK;fcntl(fd,F_SETFL,flags);}intmain(){set_nonblock(0);while(1){charbuf[1024];intnread(0,buf,sizeof(buf));if(n0){buf[n-1]0;coutbufendl;}elseif(n0){//无论是读取失败还对方的接收缓冲区没有数据最后都是n-1因此三种情况区分coutnendl;if(errnoEINTR){cout被打断了endl;continue;}elseif(errnoEAGAIN||errnoEWOULDBLOCK){sleep(1);cout没有数据endl;//虽然IO效率没有提高可以在等待的时间做自己想做的事情continue;}else{cout出错了endl;continue;}}}return0;}三. 多路转接之selectselect相关函数介绍功能系统提供select函数实现多路复用输入/输出模型用于监视多个文件描述符的状态变化程序会在select处等待直至监视的描述符有状态改变。函数原型intselect(intnfds,fd_set*readfds,fd_set*writefds,fd_set*exceptfds,structtimeval*timeout);nfds需监视的最大文件描述符值1。readfds/writefds/exceptfds分别对应可读、可写、异常文件描述符的集合。timeout设置等待时间的结构体struct timeval。文件描述符集合操作集合以位图形式存储从右到左第几位代表对应fd值用户通过以下函数操作voidFD_CLR(intfd,fd_set*set);// 清除fd在集合中intFD_ISSET(intfd,fd_set*set);// 检查fd是否在集合中voidFD_SET(intfd,fd_set*set);// 将fd添加到集合中voidFD_ZERO(fd_set*set);// 清空集合若不关心某类事件对应参数可传nullptr。timeout参数结构体含tv_sec秒和tv_usec微秒字段。若为NULL阻塞等待若字段全为0非阻塞立即返回。返回值成功返回状态改变的文件描述符数量。返回0超时时间内无描述符状态改变。返回-1发生错误错误原因存于errno涉及错误码如EBADF无效文件描述符或文件已关闭。EINTR调用被信号中断。EINVAL参数n为负值。ENOMEM内核内存不足。参数 readfds、writefds、exceptfds和 timeout的值可能变为不可预测状态后续代码不应依赖这些值。使用流程select代码编写测试基于tcp实现echo回显设计思路拿着select进行文件描述符的就绪监测(包括istenfd以及给用户开的普通的fd);当select等待到事件就绪就进行为新的连接开辟fd或者对普通fd的读写操作等;这里只检测读事件默认写都是就络的;但是select会更改输入参数导致每次都要动态维护需要监测的fd然后对d集合进行调整;因此这里采取一个数组来动态维护再进行fd集合的填充(新连接来或者有客户退出进行d数组的更新)。测试效果成功连接为新的连接开辟新的fd。普通的fd进行的读事件就绪进行正常读取。客户端退出对应fd的读事件就绪里面被写入了类似文件结尾的标志读取后直接关闭这个fd移除监测集合中对应的位置)。源码汇总点我速看源码select缺点文件描述符监控机制通过fd_set位图实现监控数量由sizeof(fd_set)决定某服务器为512字节支持最大4096个文件描述符位图容量存在上限。select的主要缺点每次调用需手动设置fd集合使用不便需将fd集合从用户态拷贝到内核态fd数量多时开销大内核需遍历所有传入的fd数量多时效率低支持的文件描述符数量上限较低依赖系统实现。局限性中的优势尽管存在上述缺点但其跨平台兼容性好因此仍被广泛使用。四.多路转接之pollpoll解决了select的部分问题主要体现在两方面突破fd数量上限select依赖固定大小数组存储文件描述符fd存在上限如1024poll改用pollfd结构体数组理论上仅受系统资源限制无固定上限。实现输入输出分离poll通过pollfd结构体中的events监听事件和revents就绪事件字段明确区分读写等事件类型无需每次全量遍历检查提升了事件处理的效率和灵活性。poll相关函数介绍poll是 Linux 系统中用于 I/O 多路复用的系统调用用于监控多个文件描述符FD的状态变化避免单线程阻塞等待 I/O。以下是其核心用法总结函数原型#includepoll.hintpoll(structpollfd*fds,nfds_tnfds,inttimeout);核心参数struct pollfd *fds如下#includepoll.hstructpollfd{intfd;shortevents;shortrevents;};监控的文件描述符列表每个元素包含三部分信息fd要监控的文件描述符如套接字、文件等。events感兴趣的事件通过宏定义指定如POLLIN、POLLOUT等。revents实际发生的事件由内核填充调用后检查该字段判断状态。nfds_t nfdsfds数组的长度即监控的文件描述符数量。int timeout超时时间单位毫秒-1永久阻塞直到有事件发生或出错。0立即返回非阻塞轮询。0最多等待指定毫秒数超时返回。返回值 0发生错误需检查errno。 0超时无任何事件发生。 0就绪的文件描述符数量fds中revents非零的元素个数。核心事件宏events/revents使用步骤初始化pollfd数组为每个需要监控的文件描述符创建struct pollfd结构体设置fd和events。structpollfdfds[2];fds[0].fdstdin_fd;// 标准输入fds[0].eventsPOLLIN;// 监控可读事件fds[1].fdsocket_fd;// 套接字fds[1].eventsPOLLIN|POLLOUT;// 监控可读和可写事件调用poll函数intretpoll(fds,2,5000);// 监控 2 个 FD最多等 5 秒处理返回结果若ret 0遍历fds数组检查revents判断哪些 FD 就绪for(inti0;infds;i){if(fds[i].reventsPOLLIN){// 处理可读事件}if(fds[i].reventsPOLLHUP){// 处理连接断开}}若ret 0超时处理。若ret 0错误处理如EINTR表示被信号中断。操作流程poll代码编写测试基于tcp实现echo回显设计思路这里只需要把对应的之前用数组维护的fd集合改成维护这个struct pollfd结构体数组对结构体里面的变量进行初始化更新判断等操作即可。测试效果同上面没啥区别。源码汇总点我速看源码特点与适用场景poll的优点接口设计更灵活不同于select使用三个位图表示fd_setpoll采用pollfd结构体指针结构体内包含要监视的事件和发生的事件避免了select“参数-值”传递方式的局限性使用更方便。文件描述符数量限制宽松poll没有最大数量限制实际受系统资源等影响仅理论上限为数组大小相比select有一定优势select通常有固定上限如1024。poll的缺点性能随监控数量线性下降当监听的文件描述符数量增多时每次调用poll都需要把大量pollfd结构从用户态拷贝到内核态并且poll返回后需轮询整个pollfd数组来获取就绪描述符若大量连接中只有少数就绪效率会显著降低如第10000个fd就绪仍需遍历全部。需手动管理就绪状态poll不自动从就绪列表中移除文件描述符需要开发者手动处理增加了代码复杂度与管理成本。存在不必要的拷贝开销每次调用poll都要将大量pollfd结构在用户态和内核态之间拷贝和select类似当监控数量大时这种拷贝带来的性能损耗不可忽视。典型场景相比epoll落后网络服务器监控多个客户端连接。同时处理文件和网络 I/O 的程序。与select的对比poll使用数组存储 FD无数量上限取决于内存而select使用fd_set通常限制为 1024。poll的事件模型更清晰通过位掩码区分事件select需重置fd_set。通过合理使用poll可以实现高效的 I/O 多路复用避免单线程阻塞导致的性能瓶颈。五.本篇小结本篇带大家简略认识五种常见的IO模型以及多路转接复用的select及poll的接口的使用也看到了有点与缺点基于poll略胜一筹但是还是比不上epoll因此下篇介绍epoll独特之处。

相关新闻

5大核心功能:让MAA成为你的明日方舟智能管家

5大核心功能:让MAA成为你的明日方舟智能管家

5大核心功能:让MAA成为你的明日方舟智能管家 【免费下载链接】MaaAssistantArknights 《明日方舟》小助手,全日常一键长草!| A one-click tool for the daily tasks of Arknights, supporting all clients. 项目地址: https://gitcode.com/…

2026/9/29 15:00:54 阅读更多 →
Adobe Illustrator批量替换终极指南:ReplaceItems.jsx让你的设计效率提升10倍

Adobe Illustrator批量替换终极指南:ReplaceItems.jsx让你的设计效率提升10倍

Adobe Illustrator批量替换终极指南:ReplaceItems.jsx让你的设计效率提升10倍 【免费下载链接】illustrator-scripts Adobe Illustrator scripts 项目地址: https://gitcode.com/gh_mirrors/il/illustrator-scripts 还在为Adobe Illustrator中繁琐的批量替换…

2026/10/9 2:10:49 阅读更多 →
DRG存档编辑器终极指南:3分钟快速部署,轻松修改《深岩银河》游戏数据

DRG存档编辑器终极指南:3分钟快速部署,轻松修改《深岩银河》游戏数据

DRG存档编辑器终极指南:3分钟快速部署,轻松修改《深岩银河》游戏数据 【免费下载链接】DRG-Save-Editor Rock and stone! 项目地址: https://gitcode.com/gh_mirrors/dr/DRG-Save-Editor DRG Save Editor是一款专为《深岩银河》(Deep …

2026/10/11 8:16:14 阅读更多 →

最新新闻

Windows平台Rust开发环境配置与优化指南

Windows平台Rust开发环境配置与优化指南

1. Rust语言与Windows环境适配背景Rust作为一门系统级编程语言,其编译器工具链对操作系统底层有着深度依赖。在Windows平台进行Rust开发需要特别注意环境配置的差异性——与Linux/macOS不同,Windows存在MSVC和GNU两种ABI(应用程序二进制接口&…

2026/10/14 2:25:24 阅读更多 →
长波红外超构透镜偏振复用FDTD仿真全流程解析

长波红外超构透镜偏振复用FDTD仿真全流程解析

1. 项目背景与核心价值长波红外超构透镜偏振复用聚焦技术是近年来光学领域的前沿研究方向。作为一名光学工程师,我在实际项目中发现传统红外光学系统存在体积大、重量沉、功能单一等问题。而基于超构表面的偏振复用透镜,能在单层平面上实现多通道光学功能…

2026/10/14 2:25:24 阅读更多 →
2026 查重率和 AIGC 率都飘红?一站式降AI率软件实测推荐

2026 查重率和 AIGC 率都飘红?一站式降AI率软件实测推荐

一、前言:2026 高校论文审核新难题随着高校学术审核体系不断升级,知网、维普等主流检测平台全面上线AIGC 智能检测功能,当代毕业生的论文写作与修改迎来双重考验。以往论文仅需攻克重复率超标问题,如今还要规避AI写作痕迹检测风险…

2026/10/14 2:25:24 阅读更多 →
摄影工作室AI提效手册:婚纱写真儿童摄影的修图、营销与交付(v1.0)

摄影工作室AI提效手册:婚纱写真儿童摄影的修图、营销与交付(v1.0)

摄影工作室AI提效手册:婚纱、写真、儿童摄影的修图营销与交付版本 v1.0  2026年10月写在前面:这本手册解决什么这本手册写给三类人:开婚纱影楼的老板与修图主管、拍个人写真和家庭照的独立摄影师、做儿童摄影工作室的店长与后期。你大概率已…

2026/10/14 2:25:24 阅读更多 →
流水线设计实战:从冒险机制到乱序执行的性能优化

流水线设计实战:从冒险机制到乱序执行的性能优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 2:25:24 阅读更多 →
【数据可视化-155】第十五届全运会乒乓球男单半决赛:樊振东VS王楚钦技术分析报告

【数据可视化-155】第十五届全运会乒乓球男单半决赛:樊振东VS王楚钦技术分析报告

🧑 博主简介:曾任某智慧城市类企业算法总监,目前在美国市场的物流公司从事高级算法工程师一职,深耕人工智能领域,精通python数据挖掘、可视化、机器学习等,发表过AI相关的专利并多次在AI类比赛中获奖。CSDN人工智能领域的优质创作者,提供AI相关的技术咨询、项目开发和个…

2026/10/14 2:24:24 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →