五种 IO 模型与非阻塞 IO

发布时间:2026/10/24 8:20:14

五种 IO 模型与非阻塞 IO 一、IO 的本质与核心矛盾在计算机世界中IO输入 / 输出的本质是数据在内存与外设如网络、磁盘之间的拷贝。但 IO 过程并非只有 “拷贝”还包含 “等待”—— 等待数据准备就绪。实际场景中等待时间往往远大于拷贝时间。因此“高效 IO” 的核心是减少等待时间的占比。二、五种 IO 模型详解为解决 “等待耗时” 问题衍生出五种 IO 模型可类比 “钓鱼” 场景理解IO 模型类比场景核心特点阻塞 IO张三死等鱼上钩啥也不干数据未就绪时系统调用阻塞直到数据准备好才拷贝非阻塞 IO李四边看书边等鱼轮询数据未就绪时系统调用立即返回错误码EWOULDBLOCK需主动轮询检查信号驱动 IO王五挂铃铛响了再收杆内核数据就绪时通过SIGIO信号通知应用应用再发起 IO 操作IO 多路转接赵六同时看多个鱼竿select/poll同时监听多个文件描述符任一就绪就处理减少等待单个 IO 的时间占比异步 IO田七雇人钓鱼钓好直接送过来内核完成 “数据准备 拷贝” 后主动通知应用应用全程不参与等待与拷贝2.1 阻塞 IO最基础的 IO 模型流程应用发起read/recv系统调用内核检查数据是否就绪若未就绪进程被挂起阻塞数据就绪后内核将数据从内核空间拷贝到用户空间拷贝完成系统调用返回进程继续执行特点实现简单是套接字默认模式等待时进程完全阻塞无法执行其他任务2.2 非阻塞 IO流程应用将文件描述符设为非阻塞通过fcntl发起read/recv若数据未就绪立即返回EWOULDBLOCK错误应用需轮询反复调用检查数据是否就绪数据就绪后拷贝数据并返回特点等待时可执行其他任务但轮询会浪费 CPU 资源仅适用于特定场景如需要持续响应的服务2.3 信号驱动 IO流程应用通过sigaction注册SIGIO信号处理函数内核数据就绪时发送SIGIO信号给应用信号处理函数中发起read/recv拷贝数据特点无需主动轮询由内核通知但信号处理逻辑复杂且拷贝时进程仍会阻塞2.4 IO 多路转接select/poll/epoll流程应用调用select传入多个文件描述符内核监听所有描述符任一就绪则返回应用找到就绪的描述符发起read/recv拷贝数据特点可同时监听多个 IO 事件减少等待占比是高性能网络编程的核心技术如 Nginx、Redis2.5 异步 IO流程应用发起异步 IO如aio_read立即返回内核自动完成 “数据准备 拷贝”拷贝完成后通过信号 / 回调通知应用特点应用全程不参与等待与拷贝效率最高但实现复杂依赖操作系统支持如 Linux 的io_uring三、同步 vs 异步阻塞 vs 非阻塞3.1 同步与异步关注 “是否参与 IO 过程”同步应用需亲自参与 IO 的 “等待” 或 “拷贝”前四种 IO 模型异步应用仅发起 IO 请求内核完成所有操作后通知仅异步 IO3.2 阻塞与非阻塞关注 “等待时的进程状态”阻塞等待时进程被挂起无法执行其他任务非阻塞等待时进程可继续执行其他任务四、非阻塞 IO 的实现与实践4.1fcntl函数设置非阻塞属性#include fcntl.h #include unistd.h // 将文件描述符设为非阻塞 void SetNonBlock(int fd) { int flags fcntl(fd, F_GETFL); // 获取当前属性 if (flags 0) { perror(fcntl F_GETFL error); return; } fcntl(fd, F_SETFL, flags | O_NONBLOCK); // 添加非阻塞标志 }4.2 非阻塞 IO 的轮询示例#include iostream #include unistd.h #include fcntl.h #include string.h #include errno.h // 回调函数类型 typedef void (*TaskFunc)(); // 模拟其他任务 void TaskA() { std::cout 执行任务A\n; } void TaskB() { std::cout 执行任务B\n; } int main() { // 1. 设置标准输入为非阻塞 SetNonBlock(STDIN_FILENO); char buf[1024]; while (true) { // 2. 非阻塞读取标准输入 ssize_t n read(STDIN_FILENO, buf, sizeof(buf) - 1); if (n 0) { // 数据就绪处理输入 buf[n] \0; std::cout 输入内容: buf std::endl; } else if (n 0) { // 输入结束 std::cout 输入结束\n; break; } else { // 3. 处理错误区分未就绪和真错误 if (errno EAGAIN || errno EWOULDBLOCK) { // 数据未就绪执行其他任务 TaskA(); TaskB(); sleep(1); // 避免CPU空转 } else if (errno EINTR) { // 被信号中断重试 continue; } else { // 其他错误 perror(read error); break; } } } return 0; }运行效果无输入时程序不会阻塞而是执行TaskA和TaskB有输入时立即读取并处理输入内容五、总结IO 的核心矛盾是 “等待耗时”五种 IO 模型从不同角度优化等待过程阻塞 IO最简单但最不灵活非阻塞 IO可并行任务但轮询耗 CPU信号驱动 IO内核通知但处理复杂IO 多路转接同时监听多 IO高性能场景首选异步 IO全程无需参与效率最高但实现复杂非阻塞 IO 是理解 “IO 优化” 的基础通过fcntl可快速实现但实际场景中更多与 IO 多路转接结合使用以达到更高的效率。
延伸阅读

更多相关文章

2026/10/23 18:55:10

TS2007FC与STM32F217ZG音频系统设计与优化

1. TS2007FC与STM32F217ZG音频系统架构解析在嵌入式音频系统设计中,TS2007FC D类音频放大器与STM32F217ZG微控制器的组合堪称黄金搭档。这套方案特别适合需要高保真音频输出的智能家居、车载音响和便携式设备场景。TS2007FC是典型的D类放大器芯片,采用PW…

2026/10/24 19:05:48

SAP CS模块详解:客户服务数字化的核心逻辑与主数据设计

简介:本资源是一份面向SAP顾问与客户服务实施人员的CS(客户服务)模块系统性入门课件,聚焦SAP CS核心功能、主数据逻辑与跨模块集成实践,特别适用于具备PM或SD模块基础的中高级顾问快速掌握服务管理全流程。课件以PPT形…

2026/10/24 19:05:48

Python实验指导部分答案高效复现指南

简介:Python语言程序设计(刘卫国)实验指导的部分答案,以doc文档形式面向Python初学者和高校相关专业学生,为实验练习提供可直接运行的代码参考。内容覆盖实验1至实验4以及实验6、实验7,具体包括π平方计算、…

2026/10/24 19:05:48

宿舍报修管理系统完整复现:SpringBoot+Vue+MySQL全栈实战

简介:面向高校毕业设计、课程实践或岗位实训的宿舍报修管理系统项目资料,适合需要完成同类课题的计算机专业学生与开发者参考。系统采用Java语言与SpringBoot框架构建后端,搭配Vue前端与MySQL数据库,涵盖用户管理、维修员管理、宿…

2026/10/24 19:05:48

博科Fabric OS存储交换机:zone配置、级联与巡检实战

简介:面向数据中心光纤存储网络运维人员与初入SAN领域的工程师,这份博科(Brocade Fabric)交换机培训文档与操作手册以25页PDF形式梳理日常运维所需的核心知识。内容从FC交换机与以太网、FC协议与TCP/IP的差异讲起,延伸…

2026/10/24 19:00:47

C类地址201.222.5.0/24切20个子网:/29掩码推导与工具对账

简介:这份实验报告面向计算机网络课程学习者与任课教师,围绕子网划分这一核心技能展开,可用于课堂实验、上机作业参考或期末复习。报告以C类地址201.222.5.0划分20个子网、每个子网约5台主机为具体案例,完整记录了实验目的与要求、…

2026/10/23 22:56:35

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

2026/10/24 0:02:40

MATLAB缩进快捷键与批量格式化实战指南

1. 被自动缩进折磨的那些年如果你写过MATLAB代码,大概率经历过这种场景:从某个文档、网页或者聊天记录里复制了一段代码,粘贴进编辑器之后,每一行前面都带着莫名其妙的空格,有的行首是四个空格,有的是一个T…

2026/10/24 0:02:40

用Poco实现Qt风格信号与槽的跨平台C++方案

简介:本资源是一份面向C中级开发者的技术实践工程,聚焦于在非Qt框架环境下模拟实现Qt核心通信机制——信号与槽,借助Poco网络库的事件系统完成解耦式对象通信。适用于需在跨平台C项目中引入松耦合回调机制、但受限于无法集成Qt依赖的开发场景…

2026/10/24 0:02:40

ESXi裸机虚拟化安装指南:从硬件兼容到虚拟机部署

1. 为什么还要折腾ESXi:从一台闲置机器说起手里攒了几台淘汰下来的迷你主机,配置不算差,i5加16G内存,扔了可惜,装个桌面系统又觉得浪费。这种场景下,ESXi就成了一个绕不开的选择。它是一套裸机虚拟化平台&a…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑