なぜ Node.js は完全なシングルスレッドではないと言えるのでしょうか?どのように理解すればよいでしょうか?次の記事でそれについて説明しますので、お役に立てれば幸いです。
node はイベント ループを使用して複数の同時実行を実現するシングルスレッド プログラムであることは誰もが知っていると思います。残念ながら、これは完全に正しいわけではありません。
では、なぜ Node.js は完全なシングルスレッド プログラムではないのでしょうか?
Node.js はシングルスレッド プログラムです*
自分たちで作成したすべての Javascript、V8、およびイベント ループは、メインとなる同じスレッドで実行されます。スレッド。
おい、これはノードがシングルスレッドであることを意味するのではないか?
しかし、おそらく、そのノードには C コードを含む多くのモジュールがあることをご存じないかもしれません。
ノードはスレッドを制御する権限をユーザーに公開しませんが、C はマルチスレッドを使用できます。
それでは、ノードはいつマルチスレッドを使用するのでしょうか?
ノード メソッドが C の synchronous メソッドをバックグラウンドで呼び出す場合、そのメソッドはすべてメイン スレッドで実行されます。
ノード メソッドが C の asynchronous メソッドをバックグラウンドで呼び出すと、メイン スレッドで実行されないことがあります。
話は簡単です。コードを見せてください。
メイン スレッドで実行される同期メソッド
Herecrypto
関連モジュールの多くは C で書かれています。以下のプログラムは、パスワードを保存するために一般的に使用されるハッシュを計算する関数です。
import { pbkdf2Sync } from "crypto"; const startTime = Date.now(); let index = 0; for (index = 0; index < 3; index++) { pbkdf2Sync("secret", "salt", 100000, 64, "sha512"); const endTime = Date.now(); console.log(`${index} time, ${endTime - startTime}`); } const endTime = Date.now(); console.log(`in the end`);
出力時間、
0 time, 44 1 time, 90 2 time, 134 in the end
毎回約 45 ミリ秒かかり、コードがメイン スレッドで順番に実行されることがわかります。
最終出力が誰になるかに注目してください。 私の CPU では、ここでのハッシュに最大 45 ミリ秒かかることに注意してください。
非同期 pbkdf2 メソッドはメイン スレッドでは実行されません
import { cpus } from "os"; import { pbkdf2 } from "crypto"; console.log(cpus().length); let startTime = console.time("time-main-end"); for (let index = 0; index < 4; index++) { startTime = console.time(`time-${index}`); pbkdf2("secret", `salt${index}`, 100000, 64, "sha512", (err, derivedKey) => { if (err) throw err; console.timeEnd(`time-${index}`); }); } console.timeEnd("time-main-end");
出力時間
time-main-end: 0.31ms time-2: 45.646ms time-0: 46.055ms time-3: 46.846ms time-1: 47.159ms
ここでわかるように、メインスレッドが早い ただし、最終的に各計算にかかる時間は 45ms です。CPU がハッシュを計算するのにかかる時間は 45ms であることを知っておく必要があります。ここのノードは間違いなくハッシュ計算に複数のスレッドを使用します。
ここで呼び出し回数を10回に変更すると時間は以下のようになり、CPUコア数を使い切るにつれて時間も増加していることがわかります。もう一度、ノードがハッシュ計算に複数のスレッドを確実に使用していることが証明されました。
time-main-end: 0.451ms time-1: 44.977ms time-2: 46.069ms time-3: 50.033ms time-0: 51.381ms time-5: 96.429ms // 注意这里,从第五次时间开始增加了 time-7: 101.61ms time-4: 113.535ms time-6: 121.429ms time-9: 151.035ms time-8: 152.585ms
ここでは、ノードでマルチスレッドが確実に有効になっていることが証明されています。しかし、少し問題がありますか?私のコンピューターの CPU は AMD R5-5600U で、6 コアと 12 スレッドがあります。しかし、5 回目から時間が増加するのはなぜですか? ノードが CPU を十分に活用していないのでしょうか? ######理由は何ですか?
ノードは事前定義されたスレッド プールを使用します。このスレッド プールのデフォルト サイズは 4 です。
export UV_THREADPOOL_SIZE=6見てみましょう例:HTTP リクエスト
import { request } from "https";
const options = {
hostname: "www.baidu.com",
port: 443,
path: "/img/PC_7ac6a6d319ba4ae29b38e5e4280e9122.png",
method: "GET",
};
let startTime = console.time(`main`);
for (let index = 0; index < 15; index++) {
startTime = console.time(`time-${index}`);
const req = request(options, (res) => {
console.log(`statusCode: ${res.statusCode}`);
console.timeEnd(`time-${index}`);
res.on("data", (d) => {
// process.stdout.write(d);
});
});
req.on("error", (error) => {
console.error(error);
});
req.end();
}
console.timeEnd("main");
main: 13.927ms
time-2: 83.247ms
time-4: 89.641ms
time-3: 91.497ms
time-12: 91.661ms
time-5: 94.677ms
.....
time-8: 134.026ms
time-1: 143.906ms
time-13: 140.914ms
time-10: 144.088ms
ここのメイン プログラムも早期に終了しました。ここでは、写真をダウンロードするための http リクエストを 15 回開始しましたが、費やした時間は 15 回ではありませんでした。乗算すると、スレッドプール/CPUの影響を受けないようです。 ######なぜ? ?ノードはスレッド プールを使用していますか?
ノードの背後にある C の
asynchronousメソッドが最初にカーネル非同期サポートがあるかどうかを確認しようとする場合、たとえば、ここではネットワークに epoll (Linux) を使用してください。非同期メソッドを提供しない場合、ノードは独自のスレッド プールを使用します。 。
したがって、http リクエストは非同期ですが、カーネルによって実装されており、カーネルが完了すると C に通知され、C はコールバックを処理するようにメインスレッドに通知します。 それでは、Node のどの非同期メソッドがスレッド プールを使用するのでしょうか?どれがそうではないでしょうか?
ネイティブ カーナル非同期
- TCP/UDP サーバー クライアントUnix ドメイン ソケット (IPC)
- パイプ
- dns.resolveXXX
- tty input(stdin など)
- Unix シグナル
- 子プロセス
- スレッド プール
- fs.*dns.lookup
- pipe (エッジ ケース)
- #This これは、ほとんどのノード最適化のエントリ ポイントでもあります。
しかし、これらを最も重要なイベント ループとどのように組み合わせるのでしょうか?
イベント ループについては、誰もがよく知っていると思います。イベント ループはディストリビュータのようなもので、
#通常の JavaScript プログラムまたはコールバックが発生すると、処理のために V8 に渡されます。- C で記述された同期メソッドが見つかった場合は、それを C に渡し、メインスレッドで実行します。
-
非同期
が発生した場合、メソッドの裏側は C で書かれています。カーネル非同期サポートがある場合は、メインスレッドからメソッドに渡されます。処理用のカーネル。 -
非同期の場合
メソッドの裏側は C で書かれています。カーネル非同期サポートがない場合は、メインスレッドからメソッドに渡されます。スレッドプール。 スレッド プールとカーネルは結果をイベント ループに返します。JavaScript コールバックが登録されている場合は、処理のために V8 に渡されます。
そして、処理するものがなくなるまでこのようにループします。
つまり、Node は完全にシングルスレッド プログラムではありません。
ノード関連の知識の詳細については、nodejs チュートリアル を参照してください。
以上がNode.js が完全なシングルスレッド プログラムではないことを理解する方法 (簡単な分析)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

CおよびJavaScriptは、WebAssemblyを介して相互運用性を実現します。 1)CコードはWebAssemblyモジュールにコンパイルされ、JavaScript環境に導入され、コンピューティングパワーが強化されます。 2)ゲーム開発では、Cは物理エンジンとグラフィックスレンダリングを処理し、JavaScriptはゲームロジックとユーザーインターフェイスを担当します。

JavaScriptは、Webサイト、モバイルアプリケーション、デスクトップアプリケーション、サーバー側のプログラミングで広く使用されています。 1)Webサイト開発では、JavaScriptはHTMLおよびCSSと一緒にDOMを運用して、JQueryやReactなどのフレームワークをサポートします。 2)ReactNativeおよびIonicを通じて、JavaScriptはクロスプラットフォームモバイルアプリケーションを開発するために使用されます。 3)電子フレームワークにより、JavaScriptはデスクトップアプリケーションを構築できます。 4)node.jsを使用すると、JavaScriptがサーバー側で実行され、高い並行リクエストをサポートします。

Pythonはデータサイエンスと自動化により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、データ処理とモデリングのためにNumpyやPandasなどのライブラリを使用して、データサイエンスと機械学習でうまく機能します。 2。Pythonは、自動化とスクリプトにおいて簡潔で効率的です。 3. JavaScriptはフロントエンド開発に不可欠であり、動的なWebページと単一ページアプリケーションの構築に使用されます。 4. JavaScriptは、node.jsを通じてバックエンド開発において役割を果たし、フルスタック開発をサポートします。

CとCは、主に通訳者とJITコンパイラを実装するために使用されるJavaScriptエンジンで重要な役割を果たします。 1)cは、JavaScriptソースコードを解析し、抽象的な構文ツリーを生成するために使用されます。 2)Cは、Bytecodeの生成と実行を担当します。 3)Cは、JITコンパイラを実装し、実行時にホットスポットコードを最適化およびコンパイルし、JavaScriptの実行効率を大幅に改善します。

現実世界でのJavaScriptのアプリケーションには、フロントエンドとバックエンドの開発が含まれます。 1)DOM操作とイベント処理を含むTODOリストアプリケーションを構築して、フロントエンドアプリケーションを表示します。 2)node.jsを介してRestfulapiを構築し、バックエンドアプリケーションをデモンストレーションします。

Web開発におけるJavaScriptの主な用途には、クライアントの相互作用、フォーム検証、非同期通信が含まれます。 1)DOM操作による動的なコンテンツの更新とユーザーインタラクション。 2)ユーザーエクスペリエンスを改善するためにデータを提出する前に、クライアントの検証が実行されます。 3)サーバーとのリフレッシュレス通信は、AJAXテクノロジーを通じて達成されます。

JavaScriptエンジンが内部的にどのように機能するかを理解することは、開発者にとってより効率的なコードの作成とパフォーマンスのボトルネックと最適化戦略の理解に役立つためです。 1)エンジンのワークフローには、3つの段階が含まれます。解析、コンパイル、実行。 2)実行プロセス中、エンジンはインラインキャッシュや非表示クラスなどの動的最適化を実行します。 3)ベストプラクティスには、グローバル変数の避け、ループの最適化、constとletsの使用、閉鎖の過度の使用の回避が含まれます。

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。


ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

VSCode Windows 64 ビットのダウンロード
Microsoft によって発売された無料で強力な IDE エディター

MinGW - Minimalist GNU for Windows
このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

mPDF
mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

PhpStorm Mac バージョン
最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

SublimeText3 英語版
推奨: Win バージョン、コードプロンプトをサポート!
