网络IO两阶段
网络IO涉及用户空间和内核空间,一般会有以下两阶段:
-
一阶段:等待数据准备就绪,即数据被copy到内核缓冲区(wait for data)
-
二阶段:数据从内核缓冲区copy到用户缓冲区(copy data from kernel to user)
根据以上两阶段不同,出现了多种网络IO模型,接下来一一进行分析。注意所展示的图中(wait for data)和(copy data from kernel to user)字段分别表示一二阶段。
1. 阻塞IO(Blocking IO)
socket fd默认blocking,从下图可以看出,用户进程全程阻塞直到两阶段完成,即,一阶段等待数据会block,二阶段将数据从内核copy到用户空间也会block,只有copy完数据后内核返回,用户进程才会解除block状态,重新运行。
结论:阻塞IO,两阶段都阻塞。
2. 非阻塞IO(Non-blocking IO)
可使用fcntl将socket设置为NON-BLOCKING,使其变为非阻塞。
fcntl(fd, F_SETFL, O_NONBLOCK);
如下图,用户进程recvfrom时,如果没有数据,则直接返回,因此一阶段不会阻塞用户进程。但是,用户进程需要不断轮询kernel数据是否准备好(会造成CPU空转,浪费资源)。当数据准备好时,用户进程会阻塞直到数据从内核空间copy到用户空间完成(二阶段),内核返回结果。
其中recvfrom<