# node的异步非阻塞特点解读

@BoyuZhou 2016-11-21 13:46:20发表于 iuap-design/blog

node的异步非阻塞特点解读

一般谈起node,伴随着的都是这样的描述:异步、非阻塞、回调和事件。基于这样的词汇,我们得出一个详尽的描述,node是基于事件驱动,采用异步非阻塞I/O机制的网络应用平台。

要理解这些特点,要知道一些重要的概念

  • 虽然我们常说Node是单线程的,这里的单线程仅仅是Javascript执行是单线程的,在Node中,内部完成I/O任务是另有线程池的。
  • 在计算资源时,除了代码不能并行执行,所有的I/O操作(网络I/O,磁盘I/O等)都是可以并行执行的。

异步I/O

Node是基于事件驱动的,所以他的执行模型,就是事件循环。每一个事件循环都会有一个或几个观察者(对,这个观察者,就是观察者模式的观察者!),而事件的执行就是由这些观察者控制是否执行加入队列的事件。(由事件的功能划分了若干观察者,每一种资源请求都划分为一个观察者,如磁盘读取、网络I/O等等)。从而实现异步I/O。

每当接收到一个请求的时候,node的javascript模块会调用底层的c++模块,对传入的回调事件进行封装成请求对象,然后放入I/O线程池等待,由观察者管控何时调用。然后Javascript线程继续执行后续的操作。

Node的底层是通过libuv来兼容不同平台事件循环,在windows下,基于IOCP实现,在*nix下基于libuv创建的多线程来实现。

非阻塞

操作系统对于I/O只有两种方式,阻塞和非阻塞,我们由一个读取文件事例来说明阻塞和非阻塞的区别,在调用阻塞I/O时,系统会等内核完成所有操作(磁盘寻址,读取数据,复制数据到内存)返回数据才结束调用,在调用非阻塞I/O时,系统内核会完成磁盘寻址,然后返回一个文件描述符,就直接结束调用,然后等程序想要获取数据时,再根据文件描述符来读取数据。

Node的非阻塞调用是使用内核的非阻塞I/O,调用后立即返回,然后等数据读取完毕后,进行事件通知,在执行数据相关操作。

总结一下,Node的事件驱动通过主循环加事件触发的方式来运行程序。由于网络I/O请求也不断的被Node服务器做异步事件处理,从而成就了Node的高并发服务器