nodejs是单线程还是多线程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nodejs是单线程还是多线程相关的知识,希望对你有一定的参考价值。

Node.js 是如何工作的?

Node.js 的主要思路是:使用非阻塞的,事件驱动的 I/O 操作来保持在处理跨平台 (across distributed devices) 数据密集型实时应用时的轻巧高效。这听起来有点绕口。

它的真正含义是,Node.js 不是一个即将主导Web开发的世界的银弹级的平台。相反,它是一个满足特别需求的平台。你肯定不会希望使用 Node.js 去做 CPU密集型操作。事实上,使用它进行繁重的计算等于摒弃 Node 几乎所有的优点。Node 真正的亮点在于建设高性能,高扩展性的互联网应用——因为它能够处理庞大的并且高吞吐量的并发连接。

它的工作原理是相当有趣的。传统的网络服务技术,是每个新增一个连接(请求)便生成一个新的线程,这个新的线程会占用系统内存,最终会占掉所有的可用内存。而 Node.js 仅仅只运行在一个单线程中,使用非阻塞的异步 I/O 调用,所有连接都由该线程处理,在 libuv 的加分下,可以允许其支持数万并发连接(全部挂在该线程的事件循环中)。

做一个简单的计算: 假设是普通的Web程序,新接入一个连接会占用 2M 的内存,在有 8GB RAM的系统上运行时, 算上线程之间上下文切换的成本,并发连接的最大理论值则为 4000 个。这是在传统 Web服务端技术下的处理情况。而 Node.js 则达到了约 1M 一个并发连接的拓展级别 (相关证明).

当然,在所有客户端的请求共享单一线程时也会有问题, 这也是一个编写 Node.js 应用的潜在缺陷. 首先, 大量的计算可能会使得 Node 的单线程暂时失去反应, 并导致所有的其他客户端的请求一直阻塞, 直到计算结束才恢复正常。 其次,开发人员需要非常小心,不要让一个 Exception 阻塞核心的事件循环,因为这将导致 Node.js 实例的终止(实际上就是程序崩溃)。( 笔者注:如 php 中某个页面挂掉是不会影响网站运行的,但是 Nodejs 是一个线程一个线程来处理所有的链接,所以不论是计算卡了或者是被异常阻塞了都可能会影响到其他所有的链接。解决方案在稍后讨论。)

参考技术A 是的。但node.js的性能不是最高的,因为javascript引擎的关系,node.js默认是单线程,一个node.js应用无法利用多核资源。不过有第三方库提供多线程支持,但不是无缝的。node.js是解决I/O瓶颈的(相对于传统技术,同步阻塞调用浪费线程),它并没有提高I/O速度,只是资源调度更高效。如果I/O速度不解决,node.js只能说能同时处理好多request,但每个request的响应时间还是那么长,甚至更长。本回答被提问者采纳

NodeJS - Event Loop 模型

最近想要深入了解一下Node.JS,关于它是单线程还是多线程的讨论很感兴趣,所以搜索了很多资料,现做一些总结整理。


//process.env.UV_THREADPOOL_SIZE=5; 可以通过更改size改变线程个数const crypto = require("crypto");const start = Date.now();
function logHashTime() { crypto.pbkdf2("a", "b", 100000, 512, "sha512", () => { console.log("Hash: ", Date.now() - start); });}logHashTime();logHashTime();logHashTime();logHashTime();
  1. Node.JS 本身是单线程的,eventLoop 也是单线程的,但是有些

    Node.JS 库不是单线程。比如  libuv 

  2.  libuv 负责处理操作系统相关的任务。 libuv 为了利用所有的CPU核,会创建一个由4个线程组成的线程池,来执行IO相关的操作。假设计算机有4个核的话,那个该线程池中的所有线程会被分别分配给那几个核。

  3. Node.JS 是单线程的,但是具体执行过程中由于用到了 libuv 这个库,底层调用操作系统的逻辑还是用 thread pool的, 所以假设你自己的电脑是CPU 4 核,当你调用 5 次 logHashTime()的时候,实际上是把前4 个logHashTime() 都分配给 4 个核,然后等某个thread 释放之后,调用最后一个logHashTime()。 所以看起来程序运行的时候仍然是多线程的,但是要知道 Node.JS 本身是单线程的。


[参考文章]

[1]https://medium.com/better-programming/is-node-js-really-single-threaded-7ea59bcc8d64

l

非Node.JS web应用的 Multi-Threaded Request Response Stateless Model 




NodeJS Single Thread Event Loop 流程图


上面两张图片结合来看就比较容易理解。


  1. 对于Node.JS的应用来说,每次client端发送的request是很多的,假设每个client发送一个request,那么这些request首先都会进入一个 event queue 事件队列,然后NodeJS的事件循环 Event Loop 会每次从队列中拿出一个事件进行处理,当没有blocking task 的时候,就直接返回response ,假设有blocking task 那就会调用 线程池中的线程对这些任务做处理(此时有可能是多线程的,根据线程池中的线程数不同而不同)。处理完之后会返回结果。

  2. 非NodeJS的web应用处理request的方式是“Multi-Threaded Request-Response” , 采用多线程并发处理客户端的请求

  3. NodeJS 采用的是 “Single Threaded with Event Loop Model” 


[参考文章]

[1]https://www.journaldev.com/7462/node-js-architecture-single-threaded-event-loop

[2]https://itnext.io/multi-threading-and-multi-process-in-node-js-ffa5bb5cde98



以上是关于nodejs是单线程还是多线程的主要内容,如果未能解决你的问题,请参考以下文章

nodejs真的是单线程吗?

c#中Timer是单线程还是多线程?

c#中Timer是单线程还是多线程

JavaScript是单线程还是多线程(转)

C#中定时器执行定时器触发任务是单线程还是多线程?

NodeJs多线程、多进程、定时任务