进程读取数据时要经过两个阶段:
1.等待内核准备数据;
2.将内核缓冲区中的数据复制到进程缓冲区中。
一、阻塞IO
进程会阻塞在等待内核准备数据和数据从内核空间复制到用户空间这两个阶段。
二、非阻塞IO
进程读取数据时,如果内核数据还没有准备好,则会立即返回一个错误告诉进程数据还没准备好。所以程序必须不断轮询询问内核数据到底准备好了没。
当内核准备好数据后,此模式还是会阻塞在从内核复制数据到用户空间的过程中,所以此模式还是属于同步IO。
三、IO多路复用
监听多个IO对象,当对象上有事件发生时,通知进程。例如select,epoll。
以select为例,用户进程会阻塞在select调用上,等待有哪些socket变成可读状态(此阶段属于内核数据准备阶段,即等待网卡获取到数据)。
当有socket变为可读状态后,用户调用recvfrom,又会阻塞在复制内核数据到进程的过程中。
所以多路复用模式的优势不是比阻塞IO处理单连接更快,而是能够在单进程中处理更多的连接。
四、异步IO(上面三个均属于同步IO)
用户调用异步读取后立即返回,然后可以去做其他工作,当内核数据准备好,并且将数据从内核空间复制到用户空间后会发出信号通知进程处理。