工作线程
【Worker threads】
node:worker_threads 模块允许使用并行执行 JavaScript 的线程。要访问它:
【The node:worker_threads module enables the use of threads that execute
JavaScript in parallel. To access it:】
import worker_threads from 'node:worker_threads';'use strict';
const worker_threads = require('node:worker_threads');Worker(线程)对于执行CPU密集型的JavaScript操作很有用。它们对I/O密集型工作帮助不大。Node.js内置的异步I/O操作比Worker更高效。
【Workers (threads) are useful for performing CPU-intensive JavaScript operations. They do not help much with I/O-intensive work. The Node.js built-in asynchronous I/O operations are more efficient than Workers can be.】
与 child_process 或 cluster 不同,worker_threads 可以共享内存。它们通过传递 ArrayBuffer 实例或共享 SharedArrayBuffer 实例来实现这一点。
【Unlike child_process or cluster, worker_threads can share memory. They do
so by transferring ArrayBuffer instances or sharing SharedArrayBuffer
instances.】
import {
Worker,
isMainThread,
parentPort,
workerData,
} from 'node:worker_threads';
if (!isMainThread) {
const { parse } = await import('some-js-parsing-library');
const script = workerData;
parentPort.postMessage(parse(script));
}
export default function parseJSAsync(script) {
return new Promise((resolve, reject) => {
const worker = new Worker(new URL(import.meta.url), {
workerData: script,
});
worker.on('message', resolve);
worker.on('error', reject);
worker.on('exit', (code) => {
if (code !== 0)
reject(new Error(`Worker stopped with exit code ${code}`));
});
});
};'use strict';
const {
Worker,
isMainThread,
parentPort,
workerData,
} = require('node:worker_threads');
if (isMainThread) {
module.exports = function parseJSAsync(script) {
return new Promise((resolve, reject) => {
const worker = new Worker(__filename, {
workerData: script,
});
worker.on('message', resolve);
worker.on('error', reject);
worker.on('exit', (code) => {
if (code !== 0)
reject(new Error(`Worker stopped with exit code ${code}`));
});
});
};
} else {
const { parse } = require('some-js-parsing-library');
const script = workerData;
parentPort.postMessage(parse(script));
}上面的例子为每个 parseJSAsync() 调用创建了一个 Worker 线程。实际上,对于这类任务应使用 Worker 池。否则,创建 Worker 的开销可能会超过它们带来的收益。
【The above example spawns a Worker thread for each parseJSAsync() call. In
practice, use a pool of Workers for these kinds of tasks. Otherwise, the
overhead of creating Workers would likely exceed their benefit.】
在实现工作池时,使用 AsyncResource API 通知诊断工具(例如提供异步堆栈跟踪)任务与其结果之间的关联。有关示例实现,请参阅 async_hooks 文档中的 为 Worker 线程池使用 AsyncResource。
【When implementing a worker pool, use the AsyncResource API to inform
diagnostic tools (e.g. to provide asynchronous stack traces) about the
correlation between tasks and their outcomes. See
"Using AsyncResource for a Worker thread pool"
in the async_hooks documentation for an example implementation.】
工作线程默认继承非进程特定的选项。请参考 Worker constructor options 了解如何自定义工作线程选项,特别是 argv 和 execArgv 选项。
【Worker threads inherit non-process-specific options by default. Refer to
Worker constructor options to know how to customize worker thread options,
specifically argv and execArgv options.】