Node.js worker_threads Module

Java FileNode.js Built-in Modules


Node.js'sworker_threadsmodule allows developers to create multiple threads in Node.js applications. Unlike the traditional single-threaded Node.js model, this module lets you execute JavaScript code in separate threads, enabling true parallel processing.

Why Multi-threading is Needed

Node.js is single-threaded by default, which means:

  1. CPU-intensive tasks will block the event loop
  2. Unable to fully utilize the performance of multi-core CPUs
  3. Long-running computations will reduce the responsiveness of the application

worker_threadsThe module solves these problems, allowing you to offload CPU-intensive tasks to other threads.


Basic Concepts

Main Thread vs Worker Thread

  1. Main thread: The main execution thread of the application, responsible for creating and managing worker threads.
  2. Worker thread: An independent execution thread created by the main thread, used to execute specific tasks.

Inter-thread Communication

Worker threads and the main thread communicate via message passing rather than shared memory. This approach avoids complex synchronization issues.


Core API

Main Components of the worker_threads Module

Example

const {
  Worker,          // Class used to create new threads
  isMainThread,    // Determine whether the current context is the main thread
  parentPort,      // Used to communicate with the parent thread
  workerData       // Data passed when the thread is created
} = require('worker_threads');

Usage Example

Create a Simple Worker Thread

Main thread code (main.js):

Example

const { Worker, isMainThread } = require('worker_threads');

if (isMainThread) {
  // Main thread code
  console.log('This is the main thread');
 
  // Create a worker thread
  const worker = new Worker('./worker.js', {
    workerData: {
      message: 'Hello, worker thread!'
    }
  });
 
  // Listen for messages from the worker thread
  worker.on('message', (msg) => {
    console.log(`Received from worker thread: ${msg}`);
  });
 
  worker.on('error', (err) => {
    console.error('Worker thread error:', err);
  });
 
  worker.on('exit', (code) => {
    if (code !== 0) {
      console.error(`Worker thread exited unexpectedly, exit code: ${code}`);
    }
  });
} else {
  // Worker thread code
  require('./worker.js');
}

Worker thread code (worker.js):

Example

const { parentPort, workerData } = require('worker_threads');

console.log('This is the worker thread');
console.log('Received message from main thread:', workerData.message);

// Simulate some work
setTimeout(() => {
  // Send a message to the main thread
  parentPort.postMessage('Work complete!');
}, 2000);

Advanced Usage

Passing Complex Data

Example

// Main thread
const worker = new Worker('./worker.js', {
  workerData: {
    array: new Uint8Array([1, 2, 3, 4]),
    object: { key: 'value' }
  }
});

// Worker thread
console.log(workerData.array);  // Uint8Array [ 1, 2, 3, 4 ]
console.log(workerData.object); // { key: 'value' }

Shared Memory (SharedArrayBuffer)

Example

// Main thread
const sharedBuffer = new SharedArrayBuffer(16);
const arr = new Uint8Array(sharedBuffer);
arr[0] = 1;

const worker = new Worker('./worker.js', {
  workerData: { sharedBuffer }
});

// Worker thread
const { sharedBuffer } = workerData;
const arr = new Uint8Array(sharedBuffer);
console.log(arr[0]); // 1

Best Practices

  1. Reasonable usage: Don't create a thread for every small task; creating threads has overhead.
  2. Error handling: Always listen for the 'error' and 'exit' events of worker threads.
  3. Resource cleanup: Ensure worker threads exit properly after completing their tasks.
  4. Communication optimization: Minimize the amount of data passed in inter-thread communication.
  5. CPU affinity: For long-running threads, consider setting CPU affinity.

Performance Considerations

  1. Thread pool: For frequent short-term tasks, consider using a thread pool pattern.
  2. Load balancing: Distribute worker threads evenly across multi-core systems.
  3. Memory usage: Each worker thread has its own V8 instance and memory space.

Common Questions

When should you use worker_threads?

  • CPU-intensive computations
  • Need to process multiple tasks in parallel
  • Need to utilize multi-core CPUs

What is the difference between worker_threads and the cluster module?

  • clusterCreates multiple Node.js processes
  • worker_threadsCreates threads that share the same process

How to debug worker threads?

Use--inspectand--inspect-brkflag, and assign a different debugging port to each worker thread.

Example

node --inspect=9229 main.js

Summary

Node.js'sworker_threadsmodule brings true multi-threading capabilities to JavaScript, allowing developers to better utilize the performance of modern multi-core CPUs. By using worker threads appropriately, you can significantly improve the performance of CPU-intensive applications while maintaining Node.js's non-blocking I/O advantages.

Java FileNode.js Built-in Modules

Other Extensions