1. 阻塞与非阻塞
- IO默认是阻塞的,设置非阻塞方法如下:
#include <fcntl.h> //需要包含的头文件
int flag = fcntl(cfd, F_GETFL);
flag |= O_NONBLOCK;
fcntl(cfd, F_SETFL, flag);
-
IO函数是否阻塞取决于连接的 fd 是否阻塞
-
阻塞与非阻塞的主要区别在与是否等待系统内核数据就绪
-
阻塞与非阻塞模型如下所示:
-
可以看到,在阻塞io模型中,即使内核数据未准备好,应用程序中的read函数也在等待;而在非阻塞io模型中,应用程序检测到系统内核数据未就绪,直接返回继续执行应用程序中的任务,但是会一直轮询查看内核中数据是否就绪。
-
但是在数据拷贝阶段,两者都是阻塞的
2. 异步与同步
- 异步:应用程序在内核数据准备阶段与数据拷贝阶段都不需要等待,这部分任务内核完成后直接通知应用程序,其实这就是异步非阻塞IO(AIO:Asynchronous no-blocking IO)。
举个例子:你去面馆打包一份面,你和阿姨说了一声,等面好了,阿姨主动给你打电话通知你面已经到你家桌子上了。 - 同步:应用程序中的同步io函数read在数据拷贝阶段需要等待
同步阻塞(BIO:blocking IO):
例子:你去面馆打包一份面,你和阿姨说了一声,阿姨叫你在这等着看他做面(数据准备阶段),做完你拿着自己的碗去装面(数据拷贝阶段),装好了回家。
同步非阻塞(NIO:non-blocking IO):
例子:你去面馆打包一份面,你和阿姨说了一声,阿姨说面没好,你继续溜达,时不时回来看看面好了没,等到面好了,你拿着自己的碗去装面(数据拷贝阶段),装好了回家。 - 那么是否有异步阻塞io呢?答案是没有的,都已经是异步了,不需要应用程序管内核的数据准备和拷贝的事了,应用程序当然就没有阻塞这一说了!
水平有限,如有错误,大家多多指正!🤭