阻塞、非阻塞、同步、异步
一个典型的网络 IO
接口调用可以分为两个阶段:数据准备和数据读写
1 数据准备
1.1 阻塞
在阻塞 IO
中,调用 IO
方法的线程会一直等待,直到数据准备就绪。这意味着线程会被阻塞,不能执行其他任务。常见的阻塞 IO
函数调用如下:
1 | ssize_t recv(int sockfd, void *buf, size_t len, int flags); |
1.2 非阻塞
在非阻塞 IO
中,调用 IO
方法的线程不会等待数据准备就绪,而是立即返回。线程可以继续执行其他任务,并通过返回值判断数据是否已经准备好。如果数据未准备好,通常会返回一个特定的错误码(例如 EAGAIN
或 EWOULDBLOCK
)。
2 数据读写
2.1 同步
通俗而言,A 操作等待 B 操作完成,得到返回值,继续处理。
通过
man recv
查看相关函数的文档
同步 IO
表示数据的读写操作是由调用者(请求方)自己来完成的,无论是阻塞还是非阻塞。在同步 IO
中,调用者必须等待数据读写操作的完成。
2.2 异步
通俗而言,A 操作告诉 B 操作它感兴趣的事件以及通知方式,然后继续处理自己的事情,B 操作在完成后通知 A 操作。
通过
man aio_read
和man aio_write
查看相关函数的文档
异步 IO
则是调用者发出请求后,可以立即继续执行其他任务,不需要等待数据读写操作完成。当数据准备好或读写操作完成后,会通过回调函数、信号等方式通知调用者。异步 IO
通常需要特殊的 API 支持,例如 aio_read
和 aio_write
。
在处理 IO
的时候,阻塞和非阻塞都是同步 IO
。只有使用了特殊的 API 才是异步 IO
3 四种 IO
模式
- 同步阻塞
IO
- 同步非阻塞
IO
- 异步阻塞
IO
- 异步非阻塞
IO
1 | /****************** 同步阻塞 *****************/ |
-------------本文结束感谢您的阅读-------------