1. 阻塞式 IO(Blocking IO)
-
工作原理:进程调用 IO 函数(如
read()、write())后,若数据未准备好,进程会被阻塞(挂起),直到数据准备完成才继续执行。 -
特点:最简单直观,编程模型简单,但当 IO 等待时,进程无法做其它事情,资源利用率低。
-
适用场景:小型程序或单线程程序,IO 操作较少。
2. 非阻塞式 IO(Non-blocking IO)
-
工作原理:进程调用 IO 函数时,如果数据未准备好,IO 函数会立即返回一个错误(通常是
EAGAIN或EWOULDBLOCK),进程不会被阻塞。 -
特点:需要程序主动轮询(polling)IO 状态,编程较复杂,但进程不会被挂起,可以执行其它任务。
-
适用场景:需要避免进程挂起、且程序能有效管理轮询机制的场景。
3. IO 复用(IO Multiplexing)
-
代表函数:
select()、poll()、epoll()(Linux 特有) -
工作原理:允许进程同时监视多个 IO 事件,内核会阻塞进程直到至少有一个 IO 事件准备就绪。
-
特点:
-
支持同时处理大量 IO 连接
-
程序不用忙等,资源利用率高
-
select和poll有文件描述符数量限制和效率问题 -
epoll支持大规模连接,性能更优
-
-
适用场景:服务器高并发网络编程,多路复用 IO。
4. 信号驱动 IO(Signal-driven IO)
-
工作原理:进程注册一个信号(如
SIGIO),当对应的文件描述符可读或可写时,内核向进程发送信号通知,进程收到信号后执行信号处理函数。 -
特点:
-
异步通知机制,避免轮询和阻塞
-
复杂度较高,信号处理需注意安全性和重入性
-
-
适用场景:需要异步事件通知且能合理处理信号的程序。
5. 异步 IO(Asynchronous IO, AIO)
-
工作原理:进程发起 IO 请求后,立刻返回继续执行其它任务,内核在后台完成 IO 操作,完成后通过信号、回调或轮询通知进程。
-
特点:
-
最高效的 IO 模型,真正的异步执行
-
编程复杂,API 支持有限,Linux 中
libaio是常见实现
-
-
适用场景:对性能要求极高的高并发环境,大文件读写等。
总结对比表
| IO模型 | 是否阻塞 | 是否异步 | 编程复杂度 | 适用场景 |
|---|---|---|---|---|
| 阻塞IO | 是 | 否 | 简单 | 小型或单线程程序 |
| 非阻塞IO | 否 | 否 | 较复杂 | 需避免阻塞,轮询管理场景 |
| IO复用 | 阻塞(内核) | 否 | 中等 | 高并发网络服务器 |
| 信号驱动IO | 否 | 是 | 复杂 | 异步事件通知场景 |
| 异步IO | 否 | 是 | 很复杂 | 高性能异步IO场景 |
如果你需要,我还能帮你写一段示例代码演示不同模型的用法,或者帮你理解哪个模型更适合某种具体需求。你觉得怎么样?
6375

被折叠的 条评论
为什么被折叠?



