图解同步/异步,阻塞/非阻塞,五种模型之差
1.6 I/O模型相关概念
1.6.1 同步/异步–消息通知机制
关注的是消息通信机制,即调用者在等待一件事情的处理结果时,被调用者是否提供完成状态的通知。
- 同步:synchronous,被调用者并不提供事件的处理结果相关的通知消息,需要调用者主动询问事情是否处理完成
- 异步:asynchronous,被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态

1.6.2 阻塞/非阻塞–等待时的状态
关注调用者在等待结果返回之前所处的状态
- 阻塞:blocking,指IO操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂起,干不了别的事情。
- 非阻塞:nonblocking,指IO操作被调用后立即返回给用户一个状态值,而无需等到IO操作彻底完成,在最终的调用结果返回之前,调用者不会被挂起,可以去做别的事情。

1.7 网络I/O模型

- 阻塞I/O模型
- 非阻塞I/O模型
- 复用I/O模型
- 信号驱动I/O模型
- 异步I/O模型

1.7.1 阻塞型I/O模型(blocking IO)
阻塞I/O模型中,进程发起一个I/O操作(如读取文件或网络数据)后,会被挂起(即阻塞),直到操作完成或数据准备好才会返回。在此期间,进程无法执行任何其他任务。它是最简单的模型,但效率低下,尤其在多连接场景下容易导致资源浪费。

1.流程图

2.技术本质
进程发起I/O调用后,被操作系统挂起,直到数据完全就绪并拷贝到用户空间才唤醒。
3.特点
- 简单易用,编程模型直观
- 全程阻塞进程,无法处理并发
- CPU利用率低(等待时不执行任何任务)
- 进程发起I/O操作后被挂起,直到内核完成数据准备与拷贝
- 调用线程处于
SLEEP
状态,不占用CPU
4.优缺点
-
优点:
-
编程简单直观(如
read()
调用后等待返回) -
无额外状态检测逻辑
-
-
缺点:
-
严重资源浪费:单线程阻塞时无法处理其他任务
-
并发能力为0:每连接需独立线程/进程,万级连接崩溃
-
1.7.2 非阻塞型I/O模型 (nonblocking IO)
非阻塞I/O模型中,进程发起I/O操作后立即返回一个状态(如“数据未就绪”),进程不会被阻塞,而是可以继续执行其他任务。但进程需要不断轮询(检测)I/O状态,直到数据准备好。这避免了无限期等待,但轮询会消耗额外CPU资源,可能导致CPU空转。

1.流程图

2.技术本质
进程发起I/O调用后立即返回状态(成功或EWOULDBLOCK
错误),需轮询检查就绪状态。
3.特点
- 进程不被挂起,可执行其他任务
- 轮询消耗大量CPU资源(忙等待)
- 延迟高(数据就绪后仍需等待轮询发现)
4.优缺点
-
优点:
-
进程不被阻塞,可执行其他计算任务
-
避免单点无限等待
-
-
缺点:
-
高CPU空转消耗:轮询占用大量CPU时间
-
响应延迟:数据就绪后仍需等待轮询发现
-
1.7.3 多路复用I/O型(I/O multiplexing)
复用I/O模型(也称为多路复用)使用一个系统调用(如select
、poll
或epoll
)同时监控多个I/O描述符(如多个网络连接)。当任何一个描述符的数据准备好时,系统调用返回,进程可以处理已就绪的I/O。它减少了轮询开销,适合高并发场景,但实现较复杂,且在数据准备好后仍需进程主动读取。

1.流程图

2.技术本质
通过单一线程监控多个I/O描述符(如select/poll/epoll
),仅当有描述符就绪时唤醒进程。
3.特点
- 高并发支持(单线程处理千级连接)
- 避免忙等待,CPU利用率高
- 就绪后仍需同步读写数据(本质仍是同步I/O)
- 编程复杂度较高(需管理多个描述符)
4.优缺点
-
优点:
-
高并发支持:单线程管理万级连接(如Nginx)
-
低CPU消耗:无忙等待,内核通知就绪事件
-
避免多线程上下文切换开销
-
-
缺点:
-
编程复杂(需管理事件队列与状态机)
-
数据就绪后仍需同步读写(本质仍为同步I/O)
-
5.I/O多路复用适用场合
- 当客户端处理多个描述符时(一般是交互式输入和网络套接口),必须使用I/O复用
- 当一个客户端同时处理多个套接字时,此情况可能的但很少出现
- 当一个服务器既要处理监听套接字,又要处理已连接套接字,一般也要用到I/O复用
- 当一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用
- 当一个服务器要处理多个服务或多个协议,一般要使用I/O复用
1.7.4 信号驱动式I/O模型 (signal-driven IO)
信号驱动I/O模型中,进程发起I/O操作后立即返回,内核在数据准备好时发送一个信号(如SIGIO
)通知进程,进程随后读取数据。进程无需轮询,而是由信号事件驱动,提高了效率。但它依赖于信号处理机制,信号处理函数可能复杂,且信号可能丢失或延误。

1.流程图

2.技术本质
进程发起I/O调用后立即返回,内核在数据就绪时发送信号(如SIGIO
) 通知进程。
3.特点
- 无轮询开销,由事件驱动
- 信号处理函数需避免阻塞操作
- 信号可能丢失或延迟(不可靠)
- 大流量场景信号队列可能溢出
4.优缺点
-
优点:
-
无轮询开销,由事件驱动响应
-
进程可专注计算任务
-
-
缺点:
-
信号可靠性差:可能丢失或延迟(尤其高并发时)
-
信号处理函数中不可调用非异步安全函数
-
跨平台兼容性差(如Windows不支持)
-
1.7.5 异步I/O模型 (asynchronous IO)
异步I/O模型中,进程发起I/O请求后立即返回,内核负责整个I/O操作(包括数据和缓冲区的处理),并在完成后通知进程(如通过回调函数)。进程完全不被阻塞,“真正异步”。它提供最高效率,但实现复杂,依赖操作系统支持(如Linux的aio
或Windows的IOCP
)。

1.流程图

2.技术本质
进程发起I/O请求(如aio_read
)后立即返回;内核负责全程操作(包括数据拷贝),完成后回调通知进程。
3.特点
- 进程全程无阻塞(真异步)
- 最高效的I/O模型(零等待时间)
- 实现复杂(需回调函数/事件循环)
- 操作系统支持有限(如Linux的
io_uring
才趋成熟)
4.优缺点
-
优点:
-
零阻塞:进程全程无需等待
-
最高效资源利用:CPU与I/O完全并行
-
适用于海量高吞吐场景(如数据库日志写入)
-
-
缺点:
-
编程复杂度高(需异步回调链或协程)
-
操作系统支持有限(Linux的
io_uring
仍处演进阶段)
-
1.8 五种IO对比
这五种I/O模型中,越往后,阻塞越少,理论上效率也是最优前四种属于同步 I/O,因为其中真正的 I/O 操作(recvfrom)将阻塞进程/线程,只有异步 I/O 模型才与 POSIX 定义的异步 I/O 相匹配

