ホームページ > 記事 > ウェブフロントエンド > Node.js + worker_threads がマルチスレッドを実装する方法について話しましょう。 (詳しい説明)
この記事では、worker_threads モジュールを理解し、worker_threads を使用して Node でマルチスレッドを実装する方法を紹介し、worker_threads を使用して実際の例としてフィボナッチ数列を実行する方法を説明します。皆さんのお役に立ちますように。
通常、Node.js
はシングルスレッドとみなされます。メインスレッドはコーディングシーケンスに従ってプログラムコードを段階的に実行しますが、同期コードがブロックされるとメインスレッドが占有され、それ以降のプログラムコードの実行が停止します。そうです、Node.js
のシングル スレッドは、メイン スレッドが「シングル スレッド」であることを指します。
単一スレッドによって引き起こされる問題を解決するために、この記事の主人公である worker_threads
が登場します。 worker_threads
は、Node.js v10.5.0
の実験的な機能として初めて登場しました。これを使用するには、コマンド ラインで --experimental-worker
を指定する必要があります。 v12.11.0
安定バージョンまで正式に使用されません。
この記事では、worker_threads
の使い方と、worker_threads
を使ってフィボナッチ数列を実行する方法を実践例として紹介します。
この記事を読んで利用するには、次のものが必要です:
Node.js v12.11.0
以降のバージョン worker_threads
このモジュールでは、JavaScript を並列実行するスレッドの使用が可能になります。
ワーカー スレッドは、CPU を集中的に使用する JavaScript 操作を実行する場合に役立ちます。これらは、I/O 集中型の作業にはあまり役に立ちません。 Node.js の組み込みの非同期 I/O 操作は、ワーカー スレッドよりも効率的です。
child_process
や cluster
とは異なり、worker_threads
はメモリを共有できます。これは、ArrayBuffer
インスタンスを転送するか、SharedArrayBuffer
インスタンスを共有することによって行われます。
worker_threads
は、次の特性により、CPU パフォーマンスを最大限に活用するための最良のソリューションであることが証明されています。
これらは、単一の複数のスレッドで実行されます。プロセス。
各スレッドはイベント ループを実行します。
JS エンジンのインスタンスをスレッドごとに 1 つ実行します。
各スレッドは単一の Nodejs インスタンスを実行します。
worker_threads
メインスレッド
指定された スクリプトを実行することにより
をファイルして作業します。各スレッドは他のスレッドから独立して実行されます。ただし、これらのスレッドはメッセージ チャネルを通じてメッセージをやり取りできます。
メイン スレッド
Use worker.postMessage()
関数はメッセージ チャネルを使用し、Worker thread
は parentPort.postMessage() を使用します。 # ##関数。
公式サンプル コードを通じて理解を深めます:
const { Worker, isMainThread, parentPort, workerData } = require('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)); }上記のコード
メイン スレッドと
Worker thread実行スクリプトと同じファイルを使用し(
__filenameは現在の実行ファイルのパス)、
isMainThreadを使用して
メインスレッドと##を区別します。 #ワーカー スレッド
ランタイム ロジック。モジュールの外部公開メソッド parseJSAsync
が呼び出されると、サブワーカー スレッドが生成され、parse
関数が実行されます。
Create ## の使用法を紹介します。 #ワーカー スレッド
workerExample.js:
const { workerData, parentPort } = require('worker_threads') parentPort.postMessage({ welcome: workerData })
作成
メイン スレッドスクリプト ファイルmain.js:
const { Worker } = require('worker_threads') const runWorker = (workerData) => { return new Promise((resolve, reject) => { // 引入 workerExample.js `工作线程`脚本文件 const worker = new Worker('./workerExample.js', { workerData }); worker.on('message', resolve); worker.on('error', reject); worker.on('exit', (code) => { if (code !== 0) reject(new Error(`stopped with ${code} exit code`)); }) }) } const main = async () => { const result = await runWorker('hello worker threads') console.log(result); } main().catch(err => console.error(err))
台湾のコマンド ライン実行の制御:
node main.js出力:
{ welcome: 'hello worker threads' }
worker_threads フィボナッチ数列演算
作成
ワーカー スレッド
worker.js
const {parentPort, workerData} = require("worker_threads"); parentPort.postMessage(getFibonacciNumber(workerData.num)) function getFibonacciNumber(num) { if (num === 0) { return 0; } else if (num === 1) { return 1; } else { return getFibonacciNumber(num - 1) + getFibonacciNumber(num - 2); } }
作成
メイン スレッドスクリプト ファイルmain.js :
const {Worker} = require("worker_threads"); let number = 30; const worker = new Worker("./worker.js", {workerData: {num: number}}); worker.once("message", result => { console.log(`${number}th Fibonacci Result: ${result}`); }); worker.on("error", error => { console.log(error); }); worker.on("exit", exitCode => { console.log(`It exited with code ${exitCode}`); }) console.log("Execution in main thread");
コンソール コマンド ライン実行:
node main.js出力:
Execution in main thread 30th Fibonacci Result: 832040 It exited with code 0
main.js
ファイルで、クラスから開始します。前の例で見たように、インスタンスはワーカー スレッドWorker を作成します。
結果を取得するために、3 つのイベントをリッスンします。
message
响应工作线程
发出消息。exit
在工作线程
停止执行的情况下触发的事件。error
发生错误时触发。我们在最后一行main.js
,
console.log("Execution in main thread");
通过控制台的输出可得,主线程
并没有被斐波那契数列运算执行而阻塞。
因此,只要在工作线程
中处理 CPU 密集型任务,我们就可以继续处理其他任务而不必担心阻塞主线程。
Node.js
在处理 CPU 密集型任务时一直因其性能而受到批评。通过有效地解决这些缺点,工作线程的引入提高了 Node.js 的功能。
有关worker_threads
的更多信息,请在此处访问其官方文档。
文章结束前留下思考,后续会在评论区做补充,欢迎一起讨论。
worker_threads
线程空闲时候会被回收吗?worker_threads
共享内存如何使用?线程
,那么应该有线程池
?更多node相关知识,请访问:nodejs 教程!
以上がNode.js + worker_threads がマルチスレッドを実装する方法について話しましょう。 (詳しい説明)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。