浅谈Node 异步IO和事件循环

2020-06-17 07:11:51易采站长站整理
磁盘IO和网络IO , 其具有两个步骤

等待数据准备 (Waiting for the data to be ready)
将数据从内核拷贝到进程中 (Copying the data from the kernel to the process)

Node中的磁盘Io

以下的讨论基于*nix系统。

理想的异步Io应该像上面讨论的一样, 如图:

而实际上, 我们的系统并不能完美的实现这样的一种调用方式, Node的异步IO, 如读取文件等采用的是线程池的方式来实现, 可以看到, Node通过另外一个线程来进行Io操作, 完成后再通知主线程:

而在window下, 则是利用 IOCP 接口来完成, IOCP从用户的角度来说确实是完美的异步调用方式, 而实际也是利用内核中的线程池, 其与nix系统的不同在于后者的线程池是用户层提供的线程池。

Node中的网络Io

在进入主题之前, 我们先了解下Linux的Io模式, 这里推荐大家看这篇文章, 大致总结如下:

阻塞 I/O(blocking IO)

所以,blocking IO的特点就是在IO执行的两个阶段都被block了。

非阻塞 I/O(nonblocking IO)

当用户进程发出read操作时,如果kernel中的数据还没有准备好,那么它并不会block用户进程,而是立刻返回一个error。从用户进程角度讲 ,它发起一个read操作后,并不需要等待,而是马上就得到了一个结果。用户进程判断结果是一个error时,它就知道数据还没有准备好,于是它可以再次发送read操作。一旦kernel中的数据准备好了,并且又再次收到了用户进程的system call,那么它马上就将数据拷贝到了用户内存,然后返回。

I/O 多路复用( IO multiplexing)

所以,I/O 多路复用的特点是通过一种机制一个进程能同时等待多个文件描述符,而这些文件描述符(套接字描述符)其中的任意一个进入读就绪状态,select()函数就可以返回。