ホームページ  >  記事  >  ウェブフロントエンド  >  Node.js におけるマルチスレッドとマルチプロセッシングの詳細な分析

Node.js におけるマルチスレッドとマルチプロセッシングの詳細な分析

青灯夜游
青灯夜游転載
2020-08-31 09:55:192571ブラウズ

Node.js におけるマルチスレッドとマルチプロセッシングの詳細な分析

Node.js は、無料のクロスプラットフォーム JavaScript ランタイム環境です。本質的にはシングルスレッドですが、バックグラウンドで複数のスレッドを使用して実行できます。非同期コード。

Node.js の非ブロック的な性質により、異なるスレッドは異なるコールバックを実行し、最初にイベント ループに委任されます。 Node.js ランタイムはこれらすべてを処理します。 [ビデオチュートリアルの推奨: node js チュートリアル]

NodeJS を使用する理由

JavaScript はもともと、Web ブラウザーでのみ実行できるシングルスレッド プログラミング言語として構築されました。これは、プロセス内では一度に 1 セットの命令のみを実行できることを意味します。

現在のコード ブロックの実行が完了した後にのみ、次のコード ブロックに移動します。ただし、JavaScript はシングルスレッドであるため、実装は簡単です。

当初、JavaScript は Web サイトに少量の対話機能を追加するためにのみ使用されていました。したがって、マルチスレッドの必要はありません。しかし時代が変わり、ユーザーの要求はさらに厳しくなり、JavaScript は「Web 上で最も人気のあるプログラミング言語」になりました。

現在、複数のスレッドが一般的になってきています。 JavaScript はシングルスレッド言語であるため、マルチスレッドを実装することはできません。幸いなことに、この場合には、Node.js という優れた解決策があります。

Node.js フレームワークは、JavaScript ランタイム環境 (特に JavaScript) の一般的な人気のおかげで不足していません。この記事を続ける前に、Node.js に関するいくつかの重要な点を理解してください。

  1. send 関数を使用すると、子プロセスから他の子プロセスやメイン プロセスにメッセージを渡すことができます
  2. 複数のプロセスのフォークのサポート
  3. ##メイン プロセスと子プロセスの間で状態は共有されません
  4. ##なぜプロセスをフォークするのですか?

2 つの場合、プロセスをフォークする必要があります:

タスクを他のプロセスに委任することで速度を向上させる
  1. メモリを解放し、単一のプロセスをアンロードする場合
  2. は、子プロセスにデータを送信したり、送り返したりすることができます。

Node.js の方法

Node.js は 2 種類のスレッドを使用します:

メイン スレッドは、イベントを介して
  1. 作業を処理します。ループ プールには多数のワーカー スレッドがあります。
  2. イベント ループは、コールバックまたは関数を取得し、将来の実行のためにそれらを登録する役割を果たします。これは、正しい JavaScript コードと同じスレッドで実行されます。 JavaScript 操作がスレッドをブロックすると、イベント ループもブロックされます。

ワーク プールは、さまざまなスレッドの生成と処理を担当する実行モデルです。タスクを同期的に実行し、結果をイベント ループに返し、最後にイベント ループが結果をコールバックに提供します。

要約すると、ワーク プールは非同期 I/O 操作、つまりシステム ディスクおよびネットワークとの対話を担当します。 fs や crypto などのモジュールは、ワーカー プールを使用する主なモジュールです。

ワーカー プールは

libuv ライブラリ

に実装されているため、Node.js では JS と C 間の内部通信にわずかな遅延が発生します。しかし、それはほとんど知覚できません。 複雑な操作を同期的に実行する必要があるまでは、すべて問題ありません。実行に長時間かかる関数は、メインスレッドのブロックを引き起こします。

プログラムに CPU を集中的に使用する機能が複数ある場合、サーバーのスループットが大幅に低下します。最悪の場合、サーバーが応答しなくなり、ワーカー プールにタスクを委任できなくなります。

AI、ビッグデータ、機械学習などのドメインでは、これらの操作によってメインスレッドがブロックされ、サーバーが応答しなくなるため、Node.js の恩恵を受けることができません。しかし、マルチスレッドのサポートが追加された Node.js v10.5.0 の登場により状況は変わります。

同時実行性と CPU 依存タスクの課題

JavaScript で同時実行性を確立するのは難しい場合があります。複数のスレッドが同じメモリにアクセスできるようにすると、競合状態が発生し、障害の再現が困難になるだけでなく、解決も困難になる可能性があります。

Node.js はもともと、非同期 I/O に基づいたサーバー側プラットフォームとして実装されました。これにより、スレッドの必要性がなくなるだけで、多くのことが簡単になります。はい、Node.js プログラムはシングルスレッドですが、一般的な方法ではありません。

Node.js で並列実行できますが、スレッドを作成する必要はありません。オペレーティング システムと仮想マシンは連携して I/O を並行して使用し、データを JavaScript コードに送り返す必要があるときに、JS コードが単一のスレッドで実行されます。

JS コード以外のすべては Node.js で並列実行されます。非同期ブロックとは異なり、JS の同期ブロックは常に一度に 1 回実行されます。 JS で I/O イベントが発生するのを待つには、コードを実行するよりもはるかに時間がかかります。

Node.js プログラムは、他のコードの実行をブロックせずに、必要な関数またはコールバックのみを呼び出します。当初、JavaScript も Node.js も、CPU を集中的に使用するタスクや CPU に依存するタスクを処理することを目的としていませんでした。

コードが最小限であれば、実行は機敏になります。ただし、計算量が増えると実行速度は遅くなります。

JS および Node で CPU を大量に使用するタスクを完了しようとすると、ブラウザーの UI がフリーズし、すべての I/O イベントがキューに入れられます。それでも、私たちは長い道のりを歩んできました。これで、worker_threads モジュールが追加されました。

worker_threads モジュールによりマルチスレッドが簡単になります

Node.js v10.5.0 が 2018 年 6 月にリリースされ、worker_threads モジュールが導入されました。これは、一般的な JavaScript ランタイム環境での同時実行性の実現に役立ちます。このモジュールを使用すると、完全に機能するマルチスレッド Node.js アプリケーションを作成できます。

技術的に言えば、ワーカー スレッドは別のスレッドで生成されるコードです。ワーカー スレッドの使用を開始するには、最初に worker_threads モジュールをインポートする必要があります。次に、Worker クラスのインスタンスを作成してワーカー スレッドを作成する必要があります。

Worker クラスのインスタンスを作成するときは、2 つのパラメーターがあります。

  1. 最初のパラメーターは、拡張子が .js または .mjs のコードが含まれるファイルへのパスを提供します。ワーカー スレッド、
  2. 2 番目のパラメータは、workerData プロパティを含むオブジェクトを提供します。このプロパティには、ワーカー スレッドが実行を開始するときにアクセスされるデータが含まれます。

セカンダリ スレッドは次のことができます。複数のメッセージ イベントをスケジュールします。したがって、コールバック メソッドは、Promise を返すよりも優先されます。

ワーカー スレッド間の通信はイベント ベースです。つまり、ワーカー スレッドがイベントを送信した直後にリスナーが呼び出されるように設定されます。最も一般的な 4 つのイベントは次のとおりです。

worker.on('error', (error) => {});
  1. ワーカー スレッドでキャッチされなかった例外があるときに発生します。次にワーカー スレッドが終了し、エラーがコールバックの最初の引数として使用できるようになります。
worker.on('exit', (exitCode) => {})
  1. セカンダリ スレッドの終了時に発行されます。 process.exit() がワーカー スレッドで呼び出された場合、exitCode がコールバックに提供されます。 worker.terminate() がワーカー スレッドを終了する場合はコード 1。
worker.on('message', (data) => {});
  1. ワーカー スレッドが親スレッドにデータを送信するときに発行されます。
worker.on('online', () => {});
  1. ワーカー スレッドが JS コードの解析を停止し、実行を開始すると発行されます。一般的には使用されませんが、特定の状況ではオンライン イベントでより多くの情報が得られる場合があります。

ワーカー スレッドの使用方法

ワーカー スレッドを使用するには 2 つの方法があります:

  • 方法 1 – 作業の生成が含まれます。コードを実行し、結果を親スレッドに送信するスレッド。この方法では、新しいタスクを実行するたびに、新しいワーカー スレッドを最初から作成する必要があります。
  • 方法 2 – ワーカー スレッドの生成とメッセージ イベントのリスナーのセットアップが含まれます。メッセージがトリガーされるたびに、ワーカー スレッドはコードを実行し、結果を親スレッドに送り返します。ワーカー スレッドは将来の使用に備えて維持されます。

方法 2 はワーカー プールとも呼ばれます。これは、この方法ではワーカーのプールを作成し、ワーカーを待機させ、必要に応じてタスクを実行するためにメッセージ イベントをディスパッチすることが含まれるためです。

ワーカー スレッドを最初から作成するには、仮想マシンを作成し、コードを解析して実行する必要があるため、公式 Node.js ドキュメントでは方法 2 を推奨しています。さらに、方法 2 は方法 1 よりも実践的で効果的です。

worker_threads モジュールで使用できる重要なプロパティ

  • isMainThread – このプロパティは、ワーカー スレッド内で動作していない場合は true です。必要に応じて、ワーカー ファイルの先頭に単純な if ステートメントを含めることができます。これにより、ワーカー スレッドとしてのみ実行されることが保証されます。
  • parentPort – 親スレッドとの通信に使用される MessagePort のインスタンス。
  • threadId – ワーカー スレッドに割り当てられた一意の識別子。
  • workerData – ワーカー スレッドのコンストラクターに含まれるデータ。

Node.js の複数のプロセス

Node.js がマルチコア システムの機能を活用するために、いくつかのプロセスを使用できます。一般的な JavaScript ランタイム環境には、複数のプロセスのサポートを提供するクラスターと呼ばれるモジュールがあります。

クラスター モジュールを使用して複数の子プロセスを生成すると、これらの子プロセスは共通のポートを共有できます。 NodeJS を使用するシステムは、子プロセスが使用されると、より大きなワークロードを処理できます。

バックエンドの Node.js

インターネットは、世界中の何百万もの企業にとって最適なプラットフォームとなっています。したがって、ビジネスがその可能性を最大限に発揮し、その過程で目立つためには、オンラインで強力な存在感を示す必要があります。

すべては強力で直感的な Web サイトから始まります。完璧な Web サイトを作成するには、最適なフロントエンド テクノロジーとバックエンド テクノロジーを選択することが重要です。本質的にはシングルスレッドですが、Node.js は バックエンド Web サービスを開発するための最初の選択肢です

バックエンドのマルチスレッド オプションが豊富であるにもかかわらず、大手企業は依然として Node.js を好みます。これは、Node.js が、すでに「Web 上で最も人気のあるプログラミング言語」である JavaScript でマルチスレッドを使用するための回避策を提供しているためです。

概要

worker_threads モジュールは、Node.js プログラムでマルチスレッドを実装する簡単な方法を提供します。大量の計算をワーカー スレッドに委任することで、サーバーのスループットを大幅に向上させることができます。

マルチスレッドのサポートにより、Node.js には、AI、ビッグデータ、機械学習などの計算集約型の分野から、ますます多くの開発者、エンジニア、その他の専門家が集まり続けるでしょう。

英語の元のアドレス: https:// flatlogic.com/blog/multi-threading-and-multiple-process-in-node-js/

読みやすさを確保するため、セックス、この記事は直訳ではなく意訳を採用しています。

プログラミング関連の知識について詳しくは、プログラミング教育をご覧ください。 !

以上がNode.js におけるマルチスレッドとマルチプロセッシングの詳細な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。