IO 阻塞与非阻塞 同步与异步
网络IO模型
IO是个我们很熟悉的操作,在操作系统的角度来讲,IO一般就是对磁盘文件的访问。但是站在网络的角度上说:
网络IO的本质是对socket的读取。
网络IO一般分为两阶段:数据准备和数据读写。
数据准备:根据系统IO操作的就绪状态分为阻塞和非阻塞
数据读写:根据应用程序和内核的交换方式分为同步和异步
陈硕大神:在处理IO的时候,阻塞与非阻塞都是同步IO。只有使用了特殊API才是异步IO
阻塞和非阻塞
下面看一段代码,我根据代码来解释阻塞和非阻塞:
int main()
{
...
char buff[128] = 0;
int size = recv(sockfd,buff,sizeof(buff),0);
if (size op 0)
{
...
}
}
当sockfd
处于阻塞模式的时候,执行这个函数的进程如果recv没接收到数据的话,就不一直阻塞(卡在这里),不执行后面的代码。
当socket处于非阻塞模式的手,执行这个函数的进程即便recv没有接收到数据(recv会返回),程序也会往下去执行其他代码。
我们可以根据recv的返回值size来判断阻塞模式
if size == -1 断开连接
if size == 0 || errno = EAGAIN 无数据,非阻塞
同步与异步
还是上面那个代码来看同步:
同步的一个例子就是:当TCP缓冲区有数据了,应用程序就会将缓冲区的数据拷贝到buff里面,然后处理数据。
由于recv函数不是异步函数,所以我接下来说的都是把它当做异步函数看的。
进程把sockfd,buff还有一个信号sigio交给操作系统,当缓冲区有数据,操作系统把数据拷贝到buff,然后发送信号通知进程,进程拿到的就是填充好的buff。
一个例子就是取饭,同步就是食堂告诉你你的饭做好了,你要去端过来;异步就是食堂再叫个外卖员把饭送到你手里。
参考文献
[1] 施磊.重写moduo库.图论科技.2020.7.
[2] 8714f2c3f1b0.网络IO模型.简书.2018.9.https://www.jianshu.com/p/a95bcb116765