Node.js + worker_threads がマルチスレッドを実装する方法について話しましょう。 (詳しい説明)

青灯夜游
リリース: 2022-02-17 20:00:23
転載
3917 人が閲覧しました

この記事では、worker_threads モジュールを理解し、worker_threads を使用してNodeでマルチスレッドを実装する方法を紹介し、worker_threads を使用して実際の例としてフィボナッチ数列を実行する方法を説明します。皆さんのお役に立ちますように。

Node.js + 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以降のバージョン
  • #JavaScript 同期および非同期プログラミングの基本知識をマスターする
  • Node.js の動作原理をマスターする

worker_threads の概要

worker_threadsこのモジュールでは、JavaScript を並列実行するスレッドの使用が可能になります。

ワーカー スレッドは、CPU を集中的に使用する JavaScript 操作を実行する場合に役立ちます。これらは、I/O 集中型の作業にはあまり役に立ちません。 Node.js の組み込みの非同期 I/O 操作は、ワーカー スレッドよりも効率的です。

child_processclusterとは異なり、worker_threadsはメモリを共有できます。これは、ArrayBufferインスタンスを転送するか、SharedArrayBufferインスタンスを共有することによって行われます。

worker_threadsは、次の特性により、CPU パフォーマンスを最大限に活用するための最良のソリューションであることが証明されています。

  • これらは、単一の複数のスレッドで実行されます。プロセス。

  • 各スレッドはイベント ループを実行します。

  • JS エンジンのインスタンスをスレッドごとに 1 つ実行します。

  • 各スレッドは単一のNodejsインスタンスを実行します。

worker_threads の仕組み

worker_threadsメインスレッド指定されたスクリプトを実行することによりをファイルして作業します。各スレッドは他のスレッドから独立して実行されます。ただし、これらのスレッドはメッセージ チャネルを通じてメッセージをやり取りできます。

メイン スレッドUseworker.postMessage()関数はメッセージ チャネルを使用し、Worker threadparentPort.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関数が実行されます。

Worker_threads 固有の使用法

このセクションでは、具体的な例を使用して、

worker_threads

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 フィボナッチ数列演算

このセクションでは、次のことを見てみましょう。 CPU 集中型の例では、フィボナッチ数列

を生成します。

このタスクがワーカー スレッドなしで完了した場合、nth

の期限が長くなるにつれてメイン スレッドがブロックされます。

作成ワーカー スレッド

スクリプト ファイル

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 サイトの他の関連記事を参照してください。

関連ラベル:
ソース:juejin.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!