Node.js我爱编程

你所看到的Node.js单线程

2017-02-25  本文已影响242人  2f1b6dfcc208

大家理所当然的都知道node.js是一个单线程。那为什么一个单线程的效率可以这么高,同时处理数万级的并发而不会造成阻塞呢?
  在官网上有这么一句话:** Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。*所以,理解了这个模型便不难回答上面的问题了。

图片1.png
  如何理解上面这张图呢?我们从左上角看起,在Node.js Application代码中,每当遇到网络请求或者其它的异步操作时,node都会把它放到Event Queue,也就是事件队列中,此时并不会立即执行它,代码也不会被阻塞,继续往下走,直到主线程代码执行完毕。
  主线程执行完毕后,开始到Event Queue的开头取出第一个事件,然后通过Event Loop,也就是事件循环机制,从线程池中分配一个线程去执行这个事件,接下来继续取出第二个事件,再从线程池中分配一个线程去执行,然后第三个,第四个。。。如果事件执行中又发起了异步操作,则把它加到事件队列的末尾。主线程不断的检查事件队列中是否有未执行的事件,直到事件队列中所有事件都执行完了,此后每当有新的事件加入到事件队列中,都会通知主线程按顺序取出交由Event Loop处理。当有事件执行完毕后,会通知主线程,主线程执行回调,线程归还给线程池。
  大致来说就是上面这个意思,这个线程池是node一开始就创建好的,线程的个数也是一定的。在Linux和Unix平台下,线程池由node自定义实现,Windows下由IOCP实现。由于Windows和
nix平台的差异,Node提供了libuv作为抽象封装层,使得所有平台兼容性的判断都由这一层来完成,并保证上层的Node与下层的自定义线程池及IOCP之间各自独立。
  所以,我们所看到的node.js单线程只是一个js主线程,本质上的异步操作还是由线程池完成的,node将所有的阻塞操作都交给了内部的线程池去实现,本身只负责不断的往返调度,并没有进行真正的I/O操作,从而实现异步非阻塞I/O,这便是node单线程的精髓之处了。

在传统模型中,大多都使用多线程来解决并发的问题,因为I/O是阻塞的,单线程就意味着用户要等待,显然这是不合理的,所以创建多个线程来响应用户的请求。

多线程对比单线程:

node中的单线程对比多线程:

总而言之,多线程与node单线程各有优缺点,在不同的场景下,选用合适的技术才是最明智的。

上一篇 下一篇

猜你喜欢

热点阅读