Lab 02: Worker Threads

Time: 30 minutes | Level: Advanced | Docker: docker run -it --rm node:20-alpine sh

Overview

Master Node.js worker threads: the worker_threads module, SharedArrayBuffer, Atomics, MessageChannel, transferable objects, worker pool pattern, and offloading CPU-bound tasks.


Step 1: Basic Worker Thread

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

if (isMainThread) {
  // Main thread — spawn worker
  const worker = new Worker(__filename, {
    workerData: { numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }
  });

  worker.on('message', result => {
    console.log('Sum from worker:', result); // 55
  });

  worker.on('error', err => console.error('Worker error:', err));
  worker.on('exit', code => {
    if (code !== 0) console.error('Worker stopped with code:', code);
  });
} else {
  // Worker thread
  const { numbers } = workerData;
  const sum = numbers.reduce((a, b) => a + b, 0);
  parentPort.postMessage(sum);
}

💡 Workers run in separate V8 contexts. They don't share heap memory (except SharedArrayBuffer).


Step 2: Worker from String (eval mode)


Step 3: SharedArrayBuffer & Atomics


Step 4: MessageChannel


Step 5: Transferable Objects

💡 Transferring ownership is O(1) and zero-copy. The original buffer becomes unusable after transfer.


Step 6: Worker Pool Pattern


Step 7: CPU-Bound Task Offloading


Step 8: Capstone — Worker fib(35)

Run verification:

📸 Verified Output:


Summary

Concept
API
Use Case

Worker creation

new Worker(file/code, opts)

Isolate CPU work

Communication

parentPort.postMessage()

Send data between threads

Shared memory

SharedArrayBuffer

Zero-copy shared state

Atomic ops

Atomics.add/load/store

Thread-safe operations

Channels

MessageChannel

Direct worker-to-worker

Transfer

transferList: [buf]

Zero-copy buffer move

Worker pool

Custom class

Manage N workers for tasks

workerData

Constructor option

Initial data to worker

Last updated