NodeJS 服务器是否使用多线程?

sat*_*ish 3 multithreading request listen node.js

我有一个关于 nodeJS 的问题(特别是关于版本 9)。使用这个项目—— https://github.com/howardchung/jsminer,我正在运行一个 nodeJS 服务器,如果这是正确的话。我通过运行在我的命令留置权上旋转它

node index.js
Run Code Online (Sandbox Code Playgroud)

这是我运行的唯一进程。例如,在“index.js”文件中,express 用于创建监听的端点

var express = require('express');
var app = express();
...
app.get('/work', function(req, res) {
    console.log("client requested work!");
    //send constructed block to client
    //client mines block
    //when client succeeds, client hits /submit
    res.json({
        result: curr_block
    });
});
Run Code Online (Sandbox Code Playgroud)

如果我打电话

http://localhost:5000/work
Run Code Online (Sandbox Code Playgroud)

同时,一个呼叫是否会被阻塞,直到另一个呼叫完成或它们被同时处理。换句话说,是否启用了多线程?

Nik*_*des 7

它的一些底层 C++ 组件可以,但该功能不会向您公开,因此您无法自己编写线程代码。Javascript 语言本身不提供对线程的支持。

要利用多个 CPU,您可以生成单独的子进程或运行同一进程的许多并行实例。

换句话说,你不能做多线程;但你仍然可以做multiprocessing

...一个呼叫是否被阻塞,直到另一个呼叫完成或它们被同时处理。

它们是并行接受的,假设您的请求主要受I/O 限制(使用数据库、文件系统等)而不是受CPU 限制(执行加密、解密、压缩等)。

Node.js 提供了一种伪并发,通过使用事件循环和程序员以事件驱动的编程风格(回调、承诺等)编写代码,而不是为每个请求创建单独的线程。

过度简化是这样的:

  • 请求 A 到达并放入事件队列。
  • 请求 A 从数据库请求数据。
  • 请求 B 到达并放入事件队列。
  • 请求 B 从数据库请求数据。
  • 请求 B 的数据库请求到达,请求 B 得到数据。
  • 请求 A 的数据库请求到达,请求 A 得到数据。

如您所见,Node 接受并发请求并在必要时为每个请求提供服务。在服务另一个请求之前,它不会停止接受传入请求。它是非阻塞的

然而,上面的场景主要是一个 I/O 绑定示例,其中 Node.js 并发模型大放异彩。

相比之下,如果您的请求主要受 CPU 限制(而不是 I/O 限制),那么您冻结它运行的单线程(记住 Node.js 是单线程的),请求无法被接受并且您的服务器“冻结”单个请求 CPU 计算的持续时间。

...换句话说,是否启用了多线程?

假设很多 Node 的底层库(例如libuv)确实使用了多线程,但是直接控制线程的能力不会暴露给用户(尽管理论上你可以编写本地C++ 插件来利用多线程)。

如果您担心没有利用所有 CPU 内核,您应该查看集群模块以启动多个 Node.js 服务器进程。在这种情况下,问题就由您解决了;在大多数情况下,O/S 调度程序应该将进程分布在可用的核心上;然而,这称为多处理,而不是多线程。