Node.js の「マルチスレッド」は同時実行性の高いタスクをどのように処理しますか?
次の記事では、nodejs 「マルチスレッド」を使用して同時実行性の高いタスクを処理する方法を紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。
関連する推奨事項: 「nodejs ビデオ チュートリアル 」
ムーアの法則
ムーア法則はインテルの共同創設者ゴードン・ムーアが1965年に提案したもので、集積回路上に収容できる部品の数は18~24か月ごとに2倍になり、性能も1倍に向上するというものだ。つまり、プロセッサー (CPU) のパフォーマンスは約 2 年ごとに 2 倍になります。
ムーアの法則が提案されてから 50 年以上が経過しました。今日、チップ部品が単一原子のスケールに近づくにつれて、ムーアの法則に従うことがますます困難になってきています。
2019 年、NVIDIA CEO の Jen-Hsun Huang 氏は ECS 展示会で次のように述べました。「ムーアの法則は、かつては 5 年ごとに 10 倍、10 年ごとに 100 倍に成長していました。しかし、現在、ムーアの法則は数倍しか成長できません」 "
単一プロセッサ (CPU) のパフォーマンスは、ますますボトルネックに近づいています。このボトルネックを突破するには、 マルチスレッド テクノロジ
を最大限に活用する必要があります。これにより、単一または複数の CPU
が複数のスレッドを同時に実行して、コンピュータ タスクをより速く完了できます。
Node のマルチスレッド
Javascript
はシングルスレッド言語であり、Nodejs
は ## を使用することは誰もが知っています。 #Javascript の機能は、イベント駆動型モデルを使用して非同期 I/O を実装し、非同期 I/O の背後にはマルチスレッド スケジューリングがあります。
Node 非同期 I/O の実装については、Pu Ling の「Node.js の詳細な紹介」を参照してください。
言語では、
Goroutine を作成して新しいスレッドを明示的に呼び出し、環境変数 GOMAXPROCS
を通じて同時実行の最大数を制御できます。 Node
には、新しいスレッドを明示的に作成できる
がありません。Node
は、次のようないくつかの非同期 I/O API を実装します。 fs.readFile
、http.request
。これらの非同期 I/O の最下層は、新しいスレッドを呼び出して非同期タスクを実行し、イベント駆動モデルを使用して実行結果を取得します。 サーバーサイド開発とツール開発では、マルチスレッド開発の使用が必要になる場合があります。たとえば、マルチスレッドを使用して複雑なクローラー タスクを処理する、マルチスレッドを使用して同時リクエストを処理する、マルチスレッドを使用してファイル処理を行う、など...
マルチスレッドを使用する場合は、次のことを制御する必要があります。同時実行の最大数。最大同時実行数は制御されないため、
の枯渇によるエラー、帯域幅不足によるネットワーク エラー、ポート制限によるエラーなどが発生する可能性があります。
Node
には同時実行の最大数を制御するための
や環境変数がないため、次に、数行の簡単なコードを使用して実装します。 。 コードの実装
まず、次のような需要シナリオを想定します。毎日 100 個のナゲット記事をクロールする必要があるクローラーがあります。1 つの記事のクロールが遅すぎる場合です。一度に 100 件の記事をクロールすると、ネットワーク接続が多すぎるため、多くのリクエストが直接失敗します。 次に、それを実装し、毎回 10 件の記事をリクエストし、10 回で完了します。これにより、効率が10倍向上するだけでなく、安定した動作も保証されます。
単一のリクエスト タスクを見てみましょう。コードは次のように実装されています:
const axios = require("axios"); async function singleRequest(article_id) { // 这里我们直接使用 axios 库进行请求 const reply = await axios.post( "https://api.juejin.cn/content_api/v1/article/detail", { article_id, } ); return reply.data; }
デモンストレーションの便宜上、ここでは同じアドレスを 100 回リクエストします。100 個のリクエスト タスクを作成しましょう. コード 実装は次のとおりです:
// 请求任务列表 const requestFnList = new Array(100) .fill("6909002738705629198") .map((id) => () => singleRequest(id));
次に、同時リクエスト メソッドを実装しましょう。このメソッドは、複数の非同期タスクの同時実行をサポートし、同時実行の最大数を制限できます。タスク プール内のタスクが実行された後、新しい非同期タスクがプッシュされて実行が継続され、タスク プールの使用率が高くなります。コードは次のように実装されます。
const chalk = require("chalk"); const { log } = require("console"); /** * 执行多个异步任务 * @param {*} fnList 任务列表 * @param {*} max 最大并发数限制 * @param {*} taskName 任务名称 */ async function concurrentRun(fnList = [], max = 5, taskName = "未命名") { if (!fnList.length) return; log(chalk.blue(`开始执行多个异步任务,最大并发数: ${max}`)); const replyList = []; // 收集任务执行结果 const count = fnList.length; // 总任务数量 const startTime = new Date().getTime(); // 记录任务执行开始时间 let current = 0; // 任务执行程序 const schedule = async (index) => { return new Promise(async (resolve) => { const fn = fnList[index]; if (!fn) return resolve(); // 执行当前异步任务 const reply = await fn(); replyList[index] = reply; log(`${taskName} 事务进度 ${((++current / count) * 100).toFixed(2)}% `); // 执行完当前任务后,继续执行任务池的剩余任务 await schedule(index + max); resolve(); }); }; // 任务池执行程序 const scheduleList = new Array(max) .fill(0) .map((_, index) => schedule(index)); // 使用 Promise.all 批量执行 const r = await Promise.all(scheduleList); const cost = (new Date().getTime() - startTime) / 1000; log(chalk.green(`执行完成,最大并发数: ${max},耗时:${cost}s`)); return replyList; }
上記のコードからわかるように、同時リクエストに
Nodeを使用するための鍵は
Promise.all、## です。 #Promise.all 複数の非同期タスクを同時に実行できます。
上記のコードでは、
max の長さの配列が作成され、対応する数の非同期タスクが配列に配置されます。次に、
Promise.all
次に、次のコードを使用して実行テストを実行します (コードは次のように実装されます)
(async () => { const requestFnList = new Array(100) .fill("6909002738705629198") .map((id) => () => singleRequest(id)); const reply = await concurrentRun(requestFnList, 10, "请求掘金文章"); })();
最終的な実行結果は以下のようになります。
#
この時点で、同時リクエストは完了です。次に、さまざまな同時実行の速度をそれぞれテストしてみましょう~ 最初は 1 つの同時実行、つまり同時実行なし (以下に示すように) です。
11.462 秒かかります。同時実行を使用しない場合、タスクには非常に長い時間がかかります。次に、他の同時実行条件 (以下に示す) でかかる時間を見てみましょう。
## 上の図からわかるように、同時実行数が増加するにつれて、タスクの実行速度はますます速くなります。 !これは高い同時実行性の利点であり、効率を数倍、場合によっては数十倍向上させることができます。
Node が実際には処理するタスクごとにスレッドを開くのではなく、非同期
タスク用に新しいスレッドを開くだけであるためです。したがって、
Node は、I/O
集中型タスクの処理には適していますが、CPU
(コンピューティング) 集中型タスクには適していません。 この時点で、同時実行性の高いタスクを処理するためのノード「マルチスレッド」の使用の導入が完了しました。プログラムをより完璧にしたい場合は、タスクのタイムアウトやフォールト トレランスのメカニズムも考慮する必要があります。興味があれば、自分で実装することもできます。
プログラミング関連の知識について詳しくは、
プログラミング入門
をご覧ください。 !
以上がNode.js の「マルチスレッド」は同時実行性の高いタスクをどのように処理しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









C++ での関数例外処理は、マルチスレッド環境でスレッドの安全性とデータの整合性を確保するために特に重要です。 try-catch ステートメントを使用すると、特定の種類の例外が発生したときにそれをキャッチして処理し、プログラムのクラッシュやデータの破損を防ぐことができます。

Java 関数を使用した同時実行およびマルチスレッド技術により、次の手順を含むアプリケーションのパフォーマンスを向上させることができます。 同時実行およびマルチスレッドの概念を理解する。 Java の同時実行性と、ExecutorService や Callable などのマルチスレッド ライブラリを活用します。マルチスレッドの行列乗算などのケースを練習して、実行時間を大幅に短縮します。同時実行性とマルチスレッドによってもたらされる、アプリケーションの応答速度の向上と最適化された処理効率の利点をお楽しみください。

マルチスレッド環境で JUnit を使用する場合、シングルスレッド テストとマルチスレッド テストという 2 つの一般的なアプローチがあります。シングルスレッド テストは同時実行性の問題を回避するためにメイン スレッドで実行されますが、マルチスレッド テストはワーカー スレッドで実行され、共有リソースが妨げられないように同期されたテスト アプローチが必要です。一般的な使用例には、マルチスレッド環境での JUnit のアプリケーションを反映する、キーと値のペアを格納するための ConcurrentHashMap の使用や、キーと値のペアを操作してその正しさを検証するための同時スレッドなど、マルチスレッド セーフなメソッドのテストが含まれます。 。

PHP マルチスレッドとは、1 つのプロセスで複数のタスクを同時に実行することを指します。これは、独立して実行されるスレッドを作成することによって実現されます。 PHP の Pthreads 拡張機能を使用して、マルチスレッド動作をシミュレートできます。インストール後、Thread クラスを使用してスレッドを作成および開始できます。たとえば、大量のデータを処理する場合、データを複数のブロックに分割し、対応する数のスレッドを作成して同時処理することで効率を向上させることができます。

マルチスレッド環境では、PHP 関数の動作はそのタイプによって異なります。 通常の関数: スレッドセーフで、同時に実行できます。グローバル変数を変更する関数: 安全ではないため、同期メカニズムを使用する必要があります。ファイル操作機能: 安全ではないため、アクセスを調整するには同期メカニズムを使用する必要があります。データベース操作機能: 安全ではないため、競合を防ぐためにデータベース システムのメカニズムを使用する必要があります。

ミューテックスは C++ でマルチスレッド共有リソースを処理するために使用されます。std::mutex を通じてミューテックスを作成します。 mtx.lock() を使用してミューテックスを取得し、共有リソースへの排他的アクセスを提供します。ミューテックスを解放するには mtx.unlock() を使用します。

マルチスレッド環境では、C++ メモリ管理はデータ競合、デッドロック、メモリ リークなどの課題に直面します。対策には次のものが含まれます: 1. ミューテックスやアトミック変数などの同期メカニズムの使用、 2. ロックフリーのデータ構造の使用、 4. (オプション) ガベージ コレクションの実装。

マルチスレッド プログラムのテストは、非再現性、同時実行エラー、デッドロック、可視性の欠如などの課題に直面しています。戦略には以下が含まれます。 単体テスト: 各スレッドの単体テストを作成して、スレッドの動作を検証します。マルチスレッド シミュレーション: シミュレーション フレームワークを使用して、スレッド スケジューリングを制御しながらプログラムをテストします。データ競合の検出: valgrind などのツールを使用して、潜在的なデータ競合を見つけます。デバッグ: デバッガー (gdb など) を使用して、ランタイム プログラムのステータスを調べ、データ競合の原因を見つけます。
