大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
Worker Threads
child_process 开独立进程;worker_threads 在同一进程内开 OS 线程,共享部分资源,适合 CPU 密集 且不想阻塞 Event Loop 的任务(加密、图像、大 JSON 解析)。
学习目标
- 创建 Worker 并传递任务与结果
- 理解
workerData与MessageChannel的传参限制 - 知道何时选 Worker 而非子进程或 cluster
最小 Worker 示例
main.js
import { Worker } from "node:worker_threads";
const worker = new Worker(new URL("./hash-worker.js", import.meta.url), {
workerData: { input: "hello" },
});
worker.on("message", (result) => {
console.log("hash:", result);
});
worker.on("error", (err) => {
console.error(err);
});
hash-worker.js
import { parentPort, workerData } from "node:worker_threads";
import { createHash } from "node:crypto";
const hash = createHash("sha256").update(workerData.input).digest("hex");
parentPort.postMessage(hash);
Worker 文件是 独立入口;不要与主线程共享可变全局对象。
传参与性能
- 结构化克隆:
postMessage复制对象(除 Transferable 如 ArrayBuffer)。 - Transferable:
postMessage(buf, [buf.buffer])零拷贝转移所有权。 - SharedArrayBuffer:多线程共享内存,需理解 Atomics(高级场景)。
避免每请求 new Worker——用 Worker 池(固定 N 个 worker 复用),否则线程创建开销抵消收益。
与 Event Loop 的关系
Worker 内 仍有 Event Loop,但 CPU 同步计算 在 worker 线程跑,不阻塞主线程 I/O。
主线程应继续处理 HTTP(node-http);重计算丢进 worker。
不适合 Worker:大量 async I/O(数据库、HTTP 客户端)——主线程 + 异步 I/O 已足够,多线程反而复杂。
错误与调试
worker.on("error", (err) => {
// 未捕获异常
});
worker.on("exit", (code) => {
if (code !== 0) console.error("worker stopped", code);
});
调试可对 worker 单独 --inspect(不同 debug port);见 nrt-debug。
与 Java 线程池对照
| Worker Threads | Java ExecutorService | |
|---|---|---|
| 模型 | 每 Worker 一个 Loop + V8 | 线程池 + 共享堆(需注意同步) |
| 数据共享 | 消息或 SAB | 共享对象需锁 |
| 典型用途 | 离线程 CPU 计算 | 通用并行 |
练习
- 写 worker 计算斐波那契第 N 项(N=40),对比主线程阻塞时的 HTTP 延迟
- 用 Transferable 传递大 ArrayBuffer,验证主线程侧 buffer 已 detached
- 实现简单池:3 个 worker 排队消费
{ id, payload }任务
小结
Worker 解决 CPU 阻塞主 Loop;I/O 密集仍用 async。 下一课 Cluster——多进程绑定多核跑 HTTP 服务。