ホームページ > 記事 > ウェブフロントエンド > 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
が複数のスレッドを同時に実行して、コンピュータ タスクをより速く完了できます。
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
には同時実行の最大数を制御するための
や環境変数がないため、次に、数行の簡単なコードを使用して実装します。 。 コードの実装
単一のリクエスト タスクを見てみましょう。コードは次のように実装されています:
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 が実際には処理するタスクごとにスレッドを開くのではなく、非同期
I/Oタスク用に新しいスレッドを開くだけであるためです。したがって、
Node は、I/O
集中型タスクの処理には適していますが、CPU
(コンピューティング) 集中型タスクには適していません。 この時点で、同時実行性の高いタスクを処理するためのノード「マルチスレッド」の使用の導入が完了しました。プログラムをより完璧にしたい場合は、タスクのタイムアウトやフォールト トレランスのメカニズムも考慮する必要があります。興味があれば、自分で実装することもできます。
プログラミング関連の知識について詳しくは、
プログラミング入門
をご覧ください。 !
以上がNode.js の「マルチスレッド」は同時実行性の高いタスクをどのように処理しますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。