Reactive Nodejs

  1. 简介
  2. 异步非阻塞IO

Everything runs in parallel except your code!

(在Node中)除了代码,一切都是并行的!

简介

Node.js 在主线程里维护了一个事件队列,当接到请求后,就将该请求作为一个事件放入这个队列中,然后继续接收其他请求。当主线程空闲时(没有请求接入时),就开始循环事件队列,检查队列中是否有要处理的事件,这时要分两种情况:如果是非 I/O 任务,就亲自处理,并通过回调函数返回到上层调用;如果是 I/O 任务,就从 线程池 中拿出一个线程来处理这个事件,并指定回调函数,然后继续循环队列中的其他事件。

当线程中的 I/O 任务完成以后,就执行指定的回调函数,并把这个完成的事件放到事件队列的尾部,等待事件循环,当主线程再次循环到该事件时,就直接处理并返回给上层调用。 这个过程就叫 事件循环 (Event Loop)

异步非阻塞IO

Node 的 异步非阻塞I/O,是建立在 C/C++ 多线程基础上

对于Node中异步I/O调用,从发起调用到内核执行完I/O操作的过渡过程中存在一种中间产物请求对象.

在Javascript层面代码会调用C++核心模块,核心模块会调用内建模块通过libuv进行系统调用.创建一个请求对象并将入参和当前方法等所有状态都封装在请求对象,包括送入线程池等待执行以及I/O操作完毕之后的回调处理.然后被推入线程池等待执行,Javascript调用至此返回继续执行当前任务的后续操作,第一阶段完成.

线程池中的I/O操作调用完成之后会保存结果然后向IOCP(还记得上面说window下基于IOCP创建么)提交执行状态告知当前对象操作完成并将线程归还线程池.中间还动用到事件循环的观察者,每次Tick都会调用IOCP相关的方法检查线程池是否有执行完的请求,有就将请求对象加入到I/O观察者的队列中当作事件处理.至此整个异步I/O流程结束.

nodejs


nodejs-io

从这里,我们可以看到,我们其实对 Node.js 的单线程一直有个误会。事实上,它的单线程指的是自身 Javascript 运行环境的单线程,Node.js 并没有给 Javascript 执行时创建新线程的能力,最终的实际操作,还是通过 Libuv 以及它的事件循环来执行的。这也就是为什么 Javascript 一个单线程的语言,能在 Node.js 里面实现异步操作的原因,两者并不冲突。

之前我们就提到了线程池的概念,发现nodejs并不是单线程的,而且还有并行事件发生。同时,线程池默认大小是 4 ,也就是说,同时能有4个线程去做文件i/o的工作,剩下的请求会被挂起等待直到线程池有空闲。 所以nodejs对于并发数,是由限制的。

线程池的大小可以通过 UV_THREADPOOL_SIZE 这个环境变量来改变 或者在nodejs代码中通过 process.env.UV_THREADPOOL_SIZE来重新设置。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 wshten@gmail.com

文章标题:Reactive Nodejs

本文作者:KevinTen

发布时间:2019-10-09, 00:00:00

最后更新:2019-10-09, 12:18:19

原始链接:http://github.com/kevinten10/2019/10/09/Reactive/Reactive-Nodejs/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏

csdn zhihu github