Node之异步I/O


在浏览器中,JavaScript在单线程上执行,而且与UI渲染共用一个线程。如果采取同步的方式,将会出现JavaScript 等待获取资源时,UI将停顿、不响应用户的交互行为。因此,异步的概念在Web2.0中火了起来。

异步I/O在Node中应用最为广泛,但是它并非Node原创。在平常的情况中,异步和非阻塞都能达到我们并行 I/O的目的,但是在计算机内核I/O中,异步/同步与阻塞/非阻塞是两回事。操作系统内核对与I/O只有两种方式: 阻塞/非阻塞。当应用层上的程序想要获取完整的数据时,它会重复调用I/O操作来确认是否完成。这种 重复调用判断操作是否完成的技术叫做轮询。关于轮询技术的发展和改进在此就不赘述了,只需知道的是 ,在应用层面上它是一种同步,并不能在时间和CPU使用效率上达到最优。

那么理想中的异步I/O是什么样子呢?如下图所示:

picture

现实比理想要骨感一些。通过让部分线程进行阻塞/非阻塞 I/O加轮询技术完成数据获取,让一个线程进行计算 处理,通过线程之间的通信将I/O得到的数据进行传递,从而实现异步I/O。

picture

上面讲解的是系统层面上对异步IO的支持,那么Node是如何实现异步I/O的呢?Node完成整个异步I/O环节有: 事件循环、观察者、请求对象、执行回调。整个异步I/O的流程如下:

picture

在Node中,除了JavaScript是单线程外,Node自身是多线程的,只是I/O线程使用的CPU较少。除了用户代码无法 并行执行外,所有的I/O(磁盘I/O和网络I/O等)则是可以并行起来的。