Node.js イベント ループの内部: 詳細
Node.js シングルスレッド モデルの探索
Node.js はイベント駆動型の非同期 I/O アプローチを採用し、シングルスレッドで同時実行性の高い JavaScript ランタイム環境を実現します。シングルスレッドは一度に 1 つのことしか実行できないことを意味します。Node.js はどのようにしてたった 1 つのスレッドで高い同時実行性と非同期 I/O を実現するのでしょうか?この記事では、この質問を中心に Node.js のシングルスレッド モデルについて説明します。
高同時実行戦略
一般に、高い同時実行性を実現する解決策は、マルチスレッド モデルを提供することです。サーバーは各クライアント要求に 1 つのスレッドを割り当て、同期 I/O を使用します。システムは、スレッド切り替えを通じて同期 I/O 呼び出しの時間コストを補います。たとえば、Apache はこの戦略を使用します。 I/O 操作には通常時間がかかるため、このアプローチで高いパフォーマンスを達成するのは困難です。ただし、非常にシンプルなので、複雑な対話ロジックを実装できます。
実際、ほとんどの Web サーバー側はあまり計算を実行しません。リクエストを受信した後、そのリクエストを他のサービス (データベースの読み取りなど) に渡し、結果が返されるのを待ち、最後に結果をクライアントに送信します。したがって、Node.js はシングルスレッド モデルを使用してこの状況に対処します。受信リクエストごとにスレッドを割り当てる代わりに、メイン スレッドを使用してすべてのリクエストを処理し、I/O 操作を非同期で処理することで、スレッドの作成、破棄、およびスレッド間の切り替えに伴うオーバーヘッドと複雑さを回避します。
イベントループ
Node.js はメインスレッドでイベント キューを維持します。リクエストを受信すると、そのリクエストはイベントとしてこのキューに追加され、その後も引き続き他のリクエストを受信します。メインスレッドがアイドル状態 (リクエストが受信されていない状態) になると、イベント キューのループを開始して、処理するイベントがあるかどうかを確認します。 2 つのケースがあります。非 I/O タスクの場合、メインスレッドはそれらを直接処理し、コールバック関数を介して上位層に戻ります。 I/O タスクの場合、スレッド プールからスレッドを取得してイベントを処理し、コールバック関数を指定して、キュー内の他のイベントをループし続けます。
スレッド内の I/O タスクが完了すると、指定されたコールバック関数が実行され、完了したイベントがイベント キューの最後に配置され、イベント ループを待ちます。メインスレッドがこのイベントを再びループすると、それを直接処理して上位層に返します。このプロセスはイベント ループと呼ばれ、その動作原理は次の図に示されています。
この図は、Node.js の全体的な動作原理を示しています。 Node.js は、左から右、上から下の順に、アプリケーション層、V8 エンジン層、Node API 層、LIBUV 層の 4 つの層に分かれています。
- アプリケーション層: JavaScript インタラクション層です。一般的な例は、http や fs などの Node.js モジュールです。
- V8 エンジン層: V8 エンジンを使用して JavaScript 構文を解析し、下位層 API と対話します。
- ノード API 層: 通常は C で実装される上位層モジュールのシステム コールを提供し、オペレーティング システムと対話します。
- LIBUV レイヤー: イベント ループ、ファイル操作などを実現するクロスプラットフォームの基礎となるカプセル化であり、非同期を実現するための Node.js の中核です。
Linux プラットフォームでも Windows プラットフォームでも、Node.js は内部でスレッド プールを使用して非同期 I/O 操作を完了し、LIBUV は異なるプラットフォームの呼び出しを統合します。したがって、Node.js のシングル スレッドは、JavaScript がシングル スレッドで実行されることを意味するだけであり、Node.js 全体がシングル スレッドであることを意味するわけではありません。
動作原理
非同期を実現する Node.js の中核はイベントにあります。つまり、すべてのタスクをイベントとして扱い、イベント ループを通じて非同期効果をシミュレートします。この事実をより具体的かつ明確に理解して受け入れるために、疑似コードを使用してその動作原理を以下に説明します。
1. イベントキューを定義する
これはキューなので、先入れ先出し (FIFO) データ構造です。 JS 配列を使用して次のように記述します。
/** * Define the event queue * Enqueue: push() * Dequeue: shift() * Empty queue: length === 0 */ let globalEventQueue = [];
配列を使用してキュー構造をシミュレートします。配列の最初の要素はキューの先頭で、最後の要素はキューの末尾です。 Push() はキューの最後に要素を挿入し、shift() はキューの先頭から要素を削除します。このようにして、単純なイベントキューが実現されます。
2. リクエスト受付口の定義
以下に示すように、すべてのリクエストがインターセプトされ、処理関数に入ります。
/** * Receive user requests * Every request will enter this function * Pass parameters request and response */ function processHttpRequest(request, response) { // Define an event object let event = createEvent({ params: request.params, // Pass request parameters result: null, // Store request results callback: function() {} // Specify a callback function }); // Add the event to the end of the queue globalEventQueue.push(event); }
この関数は、ユーザーのリクエストをイベントとしてパッケージ化してキューに入れ、他のリクエストを引き続き受信します。
3. イベントループを定義する
メインスレッドがアイドル状態になると、イベントキューのループが開始されます。したがって、イベント キューをループする関数を定義する必要があります。
/** * The main body of the event loop, executed by the main thread when appropriate * Loop through the event queue * Handle non-IO tasks * Handle IO tasks * Execute callbacks and return to the upper layer */ function eventLoop() { // If the queue is not empty, continue to loop while (this.globalEventQueue.length > 0) { // Take an event from the head of the queue let event = this.globalEventQueue.shift(); // If it's a time-consuming task if (isIOTask(event)) { // Take a thread from the thread pool let thread = getThreadFromThreadPool(); // Hand it over to the thread to handle thread.handleIOTask(event); } else { // After handling non-time-consuming tasks, directly return the result let result = handleEvent(event); // Finally, return to V8 through the callback function, and then V8 returns to the application event.callback.call(null, result); } } }
メインスレッドはイベントキューを継続的に監視します。 I/O タスクの場合はスレッド プールに渡して処理し、非 I/O タスクの場合は自身で処理して戻ります。
4. I/O タスクの処理
スレッド プールはタスクを受信した後、データベースの読み取りなどの I/O 操作を直接処理します。
/** * Define the event queue * Enqueue: push() * Dequeue: shift() * Empty queue: length === 0 */ let globalEventQueue = [];
I/O タスクが完了すると、コールバックが実行され、リクエスト結果がイベントに格納され、イベントがキューに戻されてループを待ちます。最後に、現在のスレッドが解放されます。メインスレッドがこのイベントを再度ループすると、直接処理されます。
上記のプロセスを要約すると、Node.js はリクエストの受信にメイン スレッドを 1 つだけ使用していることがわかります。リクエストを受信した後、それらを直接処理せずにイベント キューに入れ、引き続き他のリクエストを受信します。アイドル状態の場合、イベント ループを通じてこれらのイベントを処理し、非同期効果を実現します。もちろん、I/O タスクの場合は、システム レベルでスレッド プールに依存して処理する必要があります。
したがって、Node.js 自体はマルチスレッド プラットフォームですが、単一のスレッドで JavaScript レベルのタスクを処理するということが簡単に理解できます。
CPU を集中的に使用するタスクが欠点である
ここまでで、Node.js のシングルスレッド モデルについて簡単かつ明確に理解できたはずです。イベント駆動型モデルにより、高い同時実行性と非同期 I/O を実現します。ただし、Node.js が苦手な点もあります。
上で述べたように、I/O タスクの場合、Node.js はそれらをスレッド プールに渡して非同期処理を行います。これは効率的かつシンプルです。したがって、Node.js は I/O 集中型のタスクを処理するのに適しています。ただし、すべてのタスクが I/O 集中型であるわけではありません。 CPU を大量に使用するタスク、つまり、データの暗号化と復号化 (node.bcrypt.js)、データの圧縮と解凍 (node-tar) などの CPU 計算のみに依存する操作が発生した場合、Node.js はそれらを 1 つずつ処理します。 1つ。前のタスクが完了していない場合、後続のタスクは待つことしかできません。以下の図に示すように:
イベントキューでは、前の CPU 計算タスクが完了していないと、後続のタスクがブロックされ、応答が遅くなります。オペレーティング システムがシングルコアの場合は、許容できる可能性があります。しかし、現在、ほとんどのサーバーはマルチ CPU またはマルチコアであり、Node.js には EventLoop が 1 つしかありません。つまり、占有する CPU コアは 1 つだけです。 Node.js が CPU を集中的に使用するタスクによって占有され、他のタスクがブロックされると、CPU コアがアイドル状態のままになり、リソースが無駄になります。
したがって、Node.js は CPU を集中的に使用するタスクには適していません。
アプリケーションシナリオ
- RESTful API: リクエストとレスポンスには少量のテキストのみが必要で、多くの論理処理は必要ありません。したがって、数万の接続を同時に処理できます。
- チャット サービス: 軽量でトラフィック量が多く、複雑な計算ロジックはありません。
Leapcell: Web ホスティング、非同期タスク、Redis のための次世代サーバーレス プラットフォーム
最後に、Node.js サービスのデプロイに最適なプラットフォームである Leapcell を紹介します。
1. 多言語サポート
- JavaScript、Python、Go、または Rust で開発します。
2. 無制限のプロジェクトを無料でデプロイ
- 使用料金のみお支払いください。リクエストや料金はかかりません。
3. 比類のないコスト効率
- アイドル料金なしの従量課金制です。
- 例: $25 は、平均応答時間 60 ミリ秒で 694 万のリクエストをサポートします。
4. 合理化された開発者エクスペリエンス
- 直感的な UI でセットアップが簡単です。
- 完全に自動化された CI/CD パイプラインと GitOps の統合。
- 実用的な洞察を得るリアルタイムのメトリクスとログ。
5. 容易な拡張性と高性能
- 自動スケーリングにより、高い同時実行性を簡単に処理できます。
- 運用上のオーバーヘッドがゼロ - 構築だけに集中できます。
ドキュメントでさらに詳しく見てみましょう!
Leapcell Twitter: https://x.com/LeapcellHQ
以上がNode.js イベント ループの内部: 詳細の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

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

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

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

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

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

ホットトピック











JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

JavaScriptの最新トレンドには、TypeScriptの台頭、最新のフレームワークとライブラリの人気、WebAssemblyの適用が含まれます。将来の見通しは、より強力なタイプシステム、サーバー側のJavaScriptの開発、人工知能と機械学習の拡大、およびIoTおよびEDGEコンピューティングの可能性をカバーしています。

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

JavaScriptは、現代のWeb開発のコア言語であり、その多様性と柔軟性に広く使用されています。 1)フロントエンド開発:DOM操作と最新のフレームワーク(React、Vue.JS、Angularなど)を通じて、動的なWebページとシングルページアプリケーションを構築します。 2)サーバー側の開発:node.jsは、非ブロッキングI/Oモデルを使用して、高い並行性とリアルタイムアプリケーションを処理します。 3)モバイルおよびデスクトップアプリケーション開発:クロスプラットフォーム開発は、反応および電子を通じて実現され、開発効率を向上させます。

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

この記事では、許可によって保護されたバックエンドとのフロントエンド統合を示し、next.jsを使用して機能的なedtech SaaSアプリケーションを構築します。 FrontEndはユーザーのアクセス許可を取得してUIの可視性を制御し、APIリクエストがロールベースに付着することを保証します

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

私はあなたの日常的な技術ツールを使用して機能的なマルチテナントSaaSアプリケーション(EDTECHアプリ)を作成しましたが、あなたは同じことをすることができます。 まず、マルチテナントSaaSアプリケーションとは何ですか? マルチテナントSaaSアプリケーションを使用すると、Singの複数の顧客にサービスを提供できます
