Table of Contents
Start with Node threads
Some asynchronous IO will occupy additional threads
#cluster Is it multi-threaded?
True - Node multi-threading
worker_thread 模块" >worker_thread 模块
多进程 vs 多线程
Home Web Front-end JS Tutorial A brief discussion on multi-threaded operations in Nodejs

A brief discussion on multi-threaded operations in Nodejs

Jun 23, 2021 am 10:31 AM
nodejs Multithreading

Although nodejs is single-threaded, it still allows multi-threaded operations. This article will start with Node threads, talk about multi-threaded operations in Nodejs, and introduce the worker_threads template.

A brief discussion on multi-threaded operations in Nodejs

The test environment for this article:
System: macOS Mojave 10.14.2
CPU: 4 cores 2.3 GHz
Node: 10.15.1

[Recommended learning: "nodejs Tutorial"]

Start with Node threads

Most people understand Node It is single-threaded, so the number of threads should be 1 after Node is started. Let's do an experiment and see. [Recommended study: "nodejs Tutorial"]

setInterval(() => {
  console.log(new Date().getTime())
}, 3000)
Copy after login

A brief discussion on multi-threaded operations in Nodejs

You can see that the Node process occupies 7 threads. Why are there 7 threads?

We all know that the core of Node is the v8 engine. After Node is started, an instance of v8 will be created. This instance is multi-threaded.

  • Main thread: compile and execute code.
  • Compile/optimize thread: When the main thread executes, the code can be optimized.
  • Analyzer thread: records the analysis code running time to provide a basis for Crankshaft to optimize code execution.
  • Several threads for garbage collection.

So everyone often says that Node is single-threaded, which means that the execution of JavaScript is single-threaded, but the host environment of Javascript, whether it is Node or the browser, is multi-threaded.

Node has two compilers:
full-codegen: simply and quickly compile js into simple but slow machine code.
Crankshaft: A relatively complex real-time optimization compiler that compiles high-performance executable code.

Some asynchronous IO will occupy additional threads

Still the above example, we read a file while the timer is executing:

const fs = require('fs')

setInterval(() => {
    console.log(new Date().getTime())
}, 3000)

fs.readFile('./index.html', () => {})
Copy after login

A brief discussion on multi-threaded operations in Nodejs

The number of threads becomes 11. This is because there are some IO operations (DNS, FS) and some CPU-intensive calculations (Zlib, Crypto) in Node that enable Node The thread pool, and the default size of the thread pool is 4, because the number of threads becomes 11.

We can manually change the default size of the thread pool:

process.env.UV_THREADPOOL_SIZE = 64
Copy after login

Easily change the threads to 71 with one line of code.

A brief discussion on multi-threaded operations in Nodejs

#cluster Is it multi-threaded?

The single thread of Node also brings some problems, such as insufficient utilization of the CPU, an uncaught exception may cause the entire program to exit, etc. Because the cluster module is provided in Node, cluster implements the encapsulation of child_process and implements the multi-process model by creating child processes through the fork method. For example, pm2, which we use most often, is the best representative among them.

Let’s look at a cluster demo:

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  console.log(`主进程 ${process.pid} 正在运行`);
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  cluster.on(&#39;exit&#39;, (worker, code, signal) => {
    console.log(`工作进程 ${worker.process.pid} 已退出`);
  });
} else {
  // 工作进程可以共享任何 TCP 连接。
  // 在本例子中,共享的是 HTTP 服务器。
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end(&#39;Hello World&#39;);
  }).listen(8000);
  console.log(`工作进程 ${process.pid} 已启动`);
}
Copy after login

At this time, look at the activity monitor:

A brief discussion on multi-threaded operations in Nodejs

There are 9 processes in total, among which A main process, the number of CPUs x the number of CPU cores = 2 x 4 = 8 child processes.

So neither child_process nor cluster is a multi-thread model, but a multi-process model. Although developers are aware of the problems of the single-threaded model, they do not fundamentally solve the problem and provide a multi-process method to simulate multi-threading. From the previous experiments, we can see that although Node (V8) itself has multi-threading capabilities, developers cannot make good use of this capability. Instead, they use multi-threading in some ways provided by the bottom layer of Node. Node official said:

You can use the built-in Node Worker Pool by developing a C addon. On older versions of Node, build your C addon using NAN, and on newer versions use N-API . node-webworker-threads offers a JavaScript-only way to access Node's Worker Pool.

But for JavaScript developers, there has never been a standard and easy-to-use way to use Node's multi-threading capabilities. .

True - Node multi-threading

Until the release of Node 10.5.0, the official gave an experimental module worker_threads to Node Provides true multi-threading capabilities.

Let’s take a look at the simple demo first:

const {
  isMainThread,
  parentPort,
  workerData,
  threadId,
  MessageChannel,
  MessagePort,
  Worker
} = require(&#39;worker_threads&#39;);

function mainThread() {
  for (let i = 0; i < 5; i++) {
    const worker = new Worker(__filename, { workerData: i });
    worker.on(&#39;exit&#39;, code => { console.log(`main: worker stopped with exit code ${code}`); });
    worker.on(&#39;message&#39;, msg => {
      console.log(`main: receive ${msg}`);
      worker.postMessage(msg + 1);
    });
  }
}

function workerThread() {
  console.log(`worker: workerDate ${workerData}`);
  parentPort.on(&#39;message&#39;, msg => {
    console.log(`worker: receive ${msg}`);
  }),
  parentPort.postMessage(workerData);
}

if (isMainThread) {
  mainThread();
} else {
  workerThread();
}
Copy after login

The above code opens five sub-threads in the main thread, and the main thread sends simple messages to the sub-threads.

由于 worker_thread 目前仍然处于实验阶段,所以启动时需要增加 --experimental-worker flag,运行后观察活动监视器:

A brief discussion on multi-threaded operations in Nodejs

不多不少,正好多了五个子线程。

worker_thread 模块

worker_thread 核心代码

worker_thread 模块中有 4 个对象和 2 个类。

  • isMainThread: 是否是主线程,源码中是通过 threadId === 0 进行判断的。
  • MessagePort: 用于线程之间的通信,继承自 EventEmitter。
  • MessageChannel: 用于创建异步、双向通信的通道实例。
  • threadId: 线程 ID。
  • Worker: 用于在主线程中创建子线程。第一个参数为 filename,表示子线程执行的入口。
  • parentPort: 在 worker 线程里是表示父进程的 MessagePort 类型的对象,在主线程里为 null
  • workerData: 用于在主进程中向子进程传递数据(data 副本)

来看一个进程通信的例子:

const assert = require(&#39;assert&#39;);
const {
  Worker,
  MessageChannel,
  MessagePort,
  isMainThread,
  parentPort
} = require(&#39;worker_threads&#39;);
if (isMainThread) {
  const worker = new Worker(__filename);
  const subChannel = new MessageChannel();
  worker.postMessage({ hereIsYourPort: subChannel.port1 }, [subChannel.port1]);
  subChannel.port2.on(&#39;message&#39;, (value) => {
    console.log(&#39;received:&#39;, value);
  });
} else {
  parentPort.once(&#39;message&#39;, (value) => {
    assert(value.hereIsYourPort instanceof MessagePort);
    value.hereIsYourPort.postMessage(&#39;the worker is sending this&#39;);
    value.hereIsYourPort.close();
  });
}
Copy after login

更多详细用法可以查看官方文档

多进程 vs 多线程

根据大学课本上的说法:“进程是资源分配的最小单位,线程是CPU调度的最小单位”,这句话应付考试就够了,但是在实际工作中,我们还是要根据需求合理选择。

下面对比一下多线程与多进程:

属性 多进程 多线程 比较
数据 数据共享复杂,需要用IPC;数据是分开的,同步简单 因为共享进程数据,数据共享简单,同步复杂 各有千秋
CPU、内存 占用内存多,切换复杂,CPU利用率低 占用内存少,切换简单,CPU利用率高 多线程更好
销毁、切换 创建销毁、切换复杂,速度慢 创建销毁、切换简单,速度很快 多线程更好
coding 编码简单、调试方便 编码、调试复杂 多进程更好
可靠性 进程独立运行,不会相互影响 线程同呼吸共命运 多进程更好
分布式 可用于多机多核分布式,易于扩展 只能用于多核分布式 多进程更好

上述比较仅表示一般情况,并不绝对。

work_thread 让 Node 有了真正的多线程能力,算是不小的进步。

更多编程相关知识,请访问:编程视频!!

The above is the detailed content of A brief discussion on multi-threaded operations in Nodejs. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
3 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Is there a big difference between nodejs and java? Is there a big difference between nodejs and java? Apr 21, 2024 am 06:12 AM

The main differences between Node.js and Java are design and features: Event-driven vs. thread-driven: Node.js is event-driven and Java is thread-driven. Single-threaded vs. multi-threaded: Node.js uses a single-threaded event loop, and Java uses a multi-threaded architecture. Runtime environment: Node.js runs on the V8 JavaScript engine, while Java runs on the JVM. Syntax: Node.js uses JavaScript syntax, while Java uses Java syntax. Purpose: Node.js is suitable for I/O-intensive tasks, while Java is suitable for large enterprise applications.

C++ function exceptions and multithreading: error handling in concurrent environments C++ function exceptions and multithreading: error handling in concurrent environments May 04, 2024 pm 04:42 PM

Function exception handling in C++ is particularly important for multi-threaded environments to ensure thread safety and data integrity. The try-catch statement allows you to catch and handle specific types of exceptions when they occur to prevent program crashes or data corruption.

How to connect nodejs to mysql database How to connect nodejs to mysql database Apr 21, 2024 am 06:13 AM

To connect to a MySQL database, you need to follow these steps: Install the mysql2 driver. Use mysql2.createConnection() to create a connection object that contains the host address, port, username, password, and database name. Use connection.query() to perform queries. Finally use connection.end() to end the connection.

How can concurrency and multithreading of Java functions improve performance? How can concurrency and multithreading of Java functions improve performance? Apr 26, 2024 pm 04:15 PM

Concurrency and multithreading techniques using Java functions can improve application performance, including the following steps: Understand concurrency and multithreading concepts. Leverage Java's concurrency and multi-threading libraries such as ExecutorService and Callable. Practice cases such as multi-threaded matrix multiplication to greatly shorten execution time. Enjoy the advantages of increased application response speed and optimized processing efficiency brought by concurrency and multi-threading.

How to implement multi-threading in PHP? How to implement multi-threading in PHP? May 06, 2024 pm 09:54 PM

PHP multithreading refers to running multiple tasks simultaneously in one process, which is achieved by creating independently running threads. You can use the Pthreads extension in PHP to simulate multi-threading behavior. After installation, you can use the Thread class to create and start threads. For example, when processing a large amount of data, the data can be divided into multiple blocks and a corresponding number of threads can be created for simultaneous processing to improve efficiency.

How to deal with shared resources in multi-threading in C++? How to deal with shared resources in multi-threading in C++? Jun 03, 2024 am 10:28 AM

Mutexes are used in C++ to handle multi-threaded shared resources: create mutexes through std::mutex. Use mtx.lock() to obtain a mutex and provide exclusive access to shared resources. Use mtx.unlock() to release the mutex.

Challenges and countermeasures of C++ memory management in multi-threaded environment? Challenges and countermeasures of C++ memory management in multi-threaded environment? Jun 05, 2024 pm 01:08 PM

In a multi-threaded environment, C++ memory management faces the following challenges: data races, deadlocks, and memory leaks. Countermeasures include: 1. Use synchronization mechanisms, such as mutexes and atomic variables; 2. Use lock-free data structures; 3. Use smart pointers; 4. (Optional) implement garbage collection.

What is the relationship between nodejs and npm? What is the relationship between nodejs and npm? Apr 21, 2024 am 06:09 AM

Node.js is a JavaScript runtime environment and npm is its package manager. The two work together to enable developers to write server-side programs in JavaScript, use third-party modules, and easily manage modules.

See all articles