Worker Threads
Node.js で CPU 集約的な処理をメインスレッドをブロックせずに別スレッドで実行する仕組み
Node.js並行処理
Worker Threads とは
Worker Threads は、Node.js で CPU 集約的な処理をメインスレッドとは別のスレッドで実行する仕組みである。Node.js 10.5 で実験的に導入され、12 LTS で安定版になった。
Node.js はシングルスレッドのイベントループで I/O を効率的に処理するが、CPU を長時間占有する処理 (画像処理、暗号化、大量データの変換) はイベントループをブロックし、他のリクエストが処理できなくなる。Worker Threads はこの問題を解決する。
基本的な使い方
// main.ts (メインスレッド)
import { Worker } from 'worker_threads';
function runWorker(data: number[]): Promise<number> {
return new Promise((resolve, reject) => {
const worker = new Worker('./worker.ts', { workerData: data });
worker.on('message', resolve);
worker.on('error', reject);
});
}
// メインスレッドはブロックされない
const result = await runWorker([1, 2, 3, 4, 5]);
console.log('Sum:', result);
// worker.ts (ワーカースレッド)
import { parentPort, workerData } from 'worker_threads';
// CPU 集約的な処理
const sum = (workerData as number[]).reduce((a, b) => a + b, 0);
parentPort!.postMessage(sum);
イベントループとの関係
メインスレッド (イベントループ)
├── HTTP リクエストの受信・レスポンス送信
├── I/O 操作のコールバック処理
└── Worker Thread への処理委譲
Worker Thread 1: 画像リサイズ処理
Worker Thread 2: PDF 生成処理
Worker Thread 3: データ変換処理
メインスレッドは I/O とリクエストのルーティングに専念し、CPU 集約的な処理は Worker Thread に委譲する。
Worker Threads vs Child Process
| 観点 | Worker Threads | Child Process (fork) |
|---|---|---|
| メモリ | 共有可能 (SharedArrayBuffer) | 独立 (プロセス間通信が必要) |
| 起動コスト | 低い (スレッド生成) | 高い (プロセス生成) |
| 分離レベル | 同一プロセス内 | 完全に独立 |
| 適するケース | CPU 集約的な計算 | 外部コマンドの実行、クラッシュ分離 |
使うべきケースと使うべきでないケース
| 使うべき | 使うべきでない |
|---|---|
| 画像・動画の処理 | DB クエリ (I/O は非同期で十分) |
| 暗号化・ハッシュ計算 | HTTP リクエスト (I/O) |
| 大量データの変換・集計 | ファイル読み書き (I/O) |
| PDF 生成 | 単純な CRUD 処理 |
I/O バウンドな処理には Worker Threads は不要だ。Node.js の非同期 I/O で十分に効率的に処理できる。
より深く学ぶには関連書籍が役立つ。