ホームページ >ウェブフロントエンド >フロントエンドQ&A >Nodejsマルチスレッドを実装する方法

Nodejsマルチスレッドを実装する方法

WBOY
WBOYオリジナル
2023-05-08 09:09:062596ブラウズ

Node.js は、最も人気のあるバックエンド プログラミング言語の 1 つで、イベント駆動型のノンブロッキング I/O 機能により、他の言語より効率的です。

特に高い同時実行性を達成する場合、Node.js のイベント駆動型およびノンブロッキング I/O の利点が特に顕著であり、プログラムにより効率的な実行方法を提供できます。

しかし、場合によっては、CPU 集中型のタスクを処理する場合など、シングルスレッド実行モードが実際には克服できないボトルネックになる可能性があります。ただし、Node.js は問題を解決するために非同期ノンブロッキング I/O モデルを採用しています。 /O 集中型の問題を解決し、コードの複雑さを軽減します。ただし、MPI などのマルチタスク ライブラリを使用する場合も、マルチスレッド ソリューションを実装する必要があります。ただし、Node.js のシングルスレッド モデルはマルチスレッドをサポートしていないため、マルチスレッド ソリューションを実装するには他の方法を使用する必要があります。

この記事では、Node.js でマルチスレッドを実装するために使用できるソリューションのいくつかと、それらがどのような状況で最も効果的かを紹介します。

  1. 子プロセス

Node.js の子プロセス モジュールは、子プロセスを作成し、子プロセスを通じてマルチスレッド ソリューションを実装する方法を提供します。各子プロセスは独自のスレッドで実行できるため、メイン プロセスでのブロックの問題が回避されます。

子プロセス モジュールを使用すると、子プロセスで CPU を大量に使用するタスクを実行したり、タスクの割り当てやデータのやり取りにさまざまな戦略を選択したりできます。以下は、子プロセスを使用してマルチスレッド追加を実装する例です:

const { fork } = require('child_process');

// 创建子进程
const worker = fork('./worker');

// 向子进程发送数据
worker.send({a: 1, b: 2});

// 接收来自子进程的数据
worker.on('message', result => {
  console.log(result);
})

// 错误处理
worker.on('error', err => {
  console.log(err);
})

この例では、最初に子プロセス モジュールを使用して子プロセスを作成し、次にワーカーを通じて子にデータを送信します。 .send() メソッド プロセス、子プロセスは計算完了後にメイン プロセスに結果を返し、worker.on('message') メソッドを通じて戻り値を受け取ります。これにより、マルチスレッド計算が可能になります。

  1. ワーカー スレッド

Node.js は、マルチスレッドを実装する別の方法を提供します。ワーカー スレッドを使用すると、メイン スレッドから独立してサブスレッドを開始できます。このサブスレッドは時間のかかるタスクを実行できるため、シングルスレッド モデルでメイン スレッドをブロックする問題を回避できます。

子プロセスとは異なり、ワーカー スレッドはメモリを完全に共有するため、データ共有を気にせずに独立した環境で JavaScript コードを実行できます。

次は、ワーカー スレッドを使用してマルチスレッド加算を実装する例です:

const { Worker } = require('worker_threads');

function runService() {
  // 创建 Worker 线程
  const worker = new Worker(`
    const add = (a, b) => a + b;
    const { parentPort } = require('worker_threads');

    // 接收来自主线程的数据
    parentPort.on('message', message => {
      // 子线程执行加法运算
      const result = add(message.a, message.b);

      // 将结果发送给主线程
      parentPort.postMessage(result);
    });
  `);

  return worker;
}

// 启动 Worker 线程
const worker = runService();

// 向 Worker 线程发送数据
worker.postMessage({ a: 1, b: 2 });

// 接收来自 Worker 线程的数据
worker.on('message', result => {
  console.log(result);
});

// 错误处理
worker.on('error', err => {
  console.log(err);
});

ここでは、ワーカー スレッドを使用して独立したサブスレッド環境を作成し、サブスレッドが実行されます。私たちの計算ロジック。 worker.postMessage() メソッドを通じて子スレッドにデータを送信し、worker.on('message') メソッドを通じて子スレッドから返された計算結果を受け取ります。このようにして、マルチスレッド コンピューティングを実現します。

  1. Cluster

Node.js でマルチスレッドを実装するためのもう 1 つの解決策は、Node.js の Cluster モジュールを使用することです。クラスター モジュールは、接続を複数のプロセスに分散することで負荷分散を実現します。つまり、複数のプロセスを使用することで、時間のかかるタスクを処理する際のシステム パフォーマンスを大幅に向上させることができます。

場合によっては、データ並列処理の問題を処理するには、子プロセスやワーカー スレッドよりもクラスター モジュールの方が適している場合があります。 Cluster モジュールを使用するには、次の手順に従う必要があります:

const cluster = require('cluster');
const http = require('http');

if (cluster.isMaster) {
  // 获取 CPU 的核心数
  const numCPUs = require('os').cpus().length;

  // fork 子进程
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

  // 处理 worker exit 事件
  cluster.on('exit', (worker, code, signal) => {
    console.info(`Worker ${worker.process.pid} died`);
  });
} else {
  const server = http.createServer((req, res) => {
    res.writeHead(200);
    res.end(`hello world from ${process.pid}`);
  });

  server.listen(8000, () => {
    console.info(`Server running at http://localhost:8000/ in worker process with pid ${process.pid}`);
  });
}

この例では、最初にそれがメイン プロセスであるかどうかを判断します。メイン プロセスである場合は、複数の子プロセスをフォークし、それぞれの終了イベントをリッスンします。子プロセスがエラーを発生しやすくするため、メインプロセスに処理を通知します。それ以外の場合、HTTP サービスは子プロセスで作成され、現在の子プロセスの PID は listen メソッドで渡されるパラメーターによって指定されます。

概要

上記は、Node.js、子プロセス、ワーカー スレッド、クラスターでマルチスレッドを実装するための 3 つの主なソリューションです。最初の 2 つは、CPU を処理する場合の使用により適しています。集中的なタスクと後者。後者は、ネットワーク接続タスクを処理するときの使用と負荷分散に適しています。もちろん、Web ワーカーを使用したり、低レベルの C ライブラリを使用してマルチスレッドを実装したりするなど、他の解決策もあります。

上記のソリューションを使用する場合、データの正確性や共有メモリの問題など、いくつかの詳細に注意する必要がありますが、これらのソリューションの助けを借りて、効率的でスケーラブルなソリューションを提供することもできます。 Node.js アプリケーションの処理能力により、パフォーマンスが向上します。

以上がNodejsマルチスレッドを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。