太空工程师2免安装绿色版
26.9G · 2025-10-23
可以理解为程序对网络数据的“读写操作”:
读取数据(Receive / Read)
写入数据(Send / Write)
这一阶段由 操作系统内核 负责。
read()
去读取 socket:(以阻塞为例)read()
就会阻塞(等待数据就绪)。总结:数据就绪阶段就是 等待数据到达网络并被内核接受好。(网络数据进入socket读缓冲区,缓冲区标记为”可读“态)
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
上面的recv函数通过调整sockfd(文件描述符)参数,可以设置recv为“阻塞”或“非阻塞”。
默认recv为阻塞。此时调用recv,若数据还未就绪,线程就会被挂起,一致等待数据准备好再返回。
当recv为非阻塞时,如果发现数据还没就绪,直接返回。
当内核通知“数据已就绪”之后:
read()
系统调用;总结:数据读写极端就是 从内核向用户空间传输数据的过程。 (从socket 读缓冲区读取数据,或者把数据写入socket写缓冲区)
内核准备好数据后,必须应用程序通过自己把数据读出来。
同步 I/O: 程序自己搬数据,得等着。
应用程序发起请求后,操作系统完成所有IO操作,包括数据拷贝。当整个过程完成后,内核再通知应用程序。再这期间应用程序完全可以做别的事情。
异步 I/O: 系统帮你搬数据,搬完再通知你。
老师有一句非常粗暴的话“阻塞、非阻塞都是同步IO,只有调用了系统异步IO的api函数的时候才是异步IO”。
但是老师又讲到 “异步IO一般和非阻塞组合使用,因为和阻塞使用没有意义。如果使用阻塞,内核处理数据的时候,应用程序仍然挂起,没有起到提高效率的效果。”
“异步IO一般和非阻塞组合使用“。看到这句话我完全懵了。
非阻塞不是同步吗?因为非阻塞本质上也是我们在主动recv,从socket那里面拿数据啊?
寻问AI后才获得答案:
aio_read()
、io_uring
这种系统帮你全做完的。从实际工程角度来看:
这整套机制(Reactor 模式)虽然在系统角度上是同步 I/O,
但在框架层面实现了异步效果——应用不会被卡住。
我们通过“非阻塞 I/O + 事件驱动模型”模拟出了“异步”的行为效果,这其实是通过非阻塞+事件回调机制实现的 ”伪异步“。