Nodejs の非同期 I/O についての予備的な理解
この記事では、Nodejs の非同期 I/O について予備的に理解します。一定の参考値があるので、困っている友達が参考になれば幸いです。
# 「非同期」という用語は、実際には Node.js より前に生まれました。しかし、ほとんどの高級プログラミング言語では、非同期が発生することはまれです。多くの高級言語やオペレーティング プラットフォームの中で、Node は主要なプログラミング手法と設計コンセプトとして非同期を初めて使用しました。 [関連する推奨事項: "nodejs チュートリアル"]
非同期 I/O、イベント駆動型およびシングルスレッドが Node の基調を構成し、イベント駆動型および非同期 I/O 設計が構成されます。 Nginx と Node の概念は比較的似ています。 Nginx は純粋な C で書かれており、優れたパフォーマンスを備え、クライアントの接続を管理する強力な機能を備えていますが、依然としてさまざまな同期プログラミング言語による制限があります。しかし、Node は万能であり、クライアントからの大量の同時リクエストを処理するサーバーとして使用したり、ネットワーク内のさまざまなアプリケーションに同時リクエストを行うクライアントとしても使用できます。
非同期 I/O
なぜ非同期 I/O が Node で非常に重要なのか?これは、Node がネットワーク用に設計されているためです。 , 同時実行性は、現代のプログラミングの標準機能になっています。
ユーザー エクスペリエンス
「高パフォーマンス JavaScript」では、スクリプトの実行時間が 100 ミリ秒を超えると、ユーザーは、ページが停止しています。ページが応答を停止したと考えてください。 B/S モデルでは、ネットワーク速度の制限により、Web ページのリアルタイム エクスペリエンスに大きな問題が発生します。
Web ページが一時的にリソースを取得して同期的に取得する必要がある場合、JavaScript は実行を続行する前に、サーバーからリソースが完全に取得されるまで待つ必要があります。この間、UI は一時停止し、ユーザーのインタラクションに応答しません。このようなユーザー エクスペリエンスは非常に悪くなります。非同期リクエストでは、リソースのダウンロード中に JavaScript と UI の実行が待機状態にならず、ユーザーの操作に応答し続けることができます。
同様に、フロントエンドは非同期使用によって UI のブロックを排除できますが、フロントエンドがリソースを取得する速度はバックエンドの応答速度にも依存します。リソースが 2 つの異なる場所から返されたデータから得られる場合、最初のリソースは M ミリ秒を消費し、2 番目のリソースは N ミリ秒を消費します。同期方式を使用する場合、2 つのリソースを取得するのにかかる時間は M N ミリ秒です。非同期方式では、最初のリソースの取得は 2 番目のリソースの取得をブロックせず、消費される時間は max(M,N) です。
Web サイトまたはアプリケーションが拡大し続けるにつれて、M と N の値は直線的に増加し、非同期のパフォーマンスが同期よりも優れるようになります。
リソースの割り当て
ビジネス シナリオで完了する必要がある一連の無関係なタスクがあると仮定すると、次の 2 つの主流の方法があります。
- 一度にシングルスレッドでシリアル実行
- マルチスレッドの並列完了
非同期 I/O の実装
非同期 I/O は Node で最も広く使用されていますが、Node 独自のものではありません。
非同期 I/O とノンブロッキング I/O
コンピュータ カーネル I/O には、非同期/同期とブロッキング/ノンブロッキングの 2 つがあります。異なるもの。 。 オペレーティング システムの I/O 方式は、ブロッキングとノンブロッキングの 2 つだけです。ブロッキング I/O を呼び出す場合、アプリケーションは結果を返す前に I/O が完了するまで待つ必要があります。 ブロッキング I/O の特性の 1 つは、呼び出し後、呼び出しが終了する前にシステム カーネル レベルがすべての操作を完了するまで待機する必要があることです。 I/O をブロックすると、CPU が I/O を待つことになり、待ち時間が無駄になり、CPU の処理能力を十分に活用できなくなります。 パフォーマンスを向上させるために、カーネルはノンブロッキング I/O を提供します。ノンブロッキング I/O とブロッキング I/O の違いは、呼び出し直後に戻ることです。ノンブロッキング I/O が戻った後は、CPU タイム スライスを他の処理に使用できます。パフォーマンスの向上は明らかですが、I/O が完了していないため、すぐに返されるのはビジネス層が期待するデータではなく、現在の呼び出しステータスのみです。 完全なデータを取得するには、アプリケーションは I/O 操作を繰り返し呼び出して、完了したかどうかを確認する必要があります。操作が完了したかどうかを判断するために繰り返し呼び出しを行うこの手法は、ポーリングと呼ばれます。
既存のポーリング テクノロジには、主に read、select、poll、epoll、kqueue が含まれます。ここでは、epoll のポーリング原理についてのみ説明します。epoll は、Linux で最も効率的な I/O イベント通知メカニズムです。ポーリングを開始するときに、I/O イベントが検出されない場合、イベントが発生して起動するまでスリープ状態になります。クエリを走査する代わりにイベント通知と実行コールバック メソッドを実際に使用するため、CPU を無駄にせず、実行効率が高くなります。
ポーリング テクノロジは、完全なデータを確実に取得するためのノンブロッキング I/O のニーズを満たしますが、プログラムにとっては依然として一種の同期とみなされます。アプリケーションはまだ I/O が完全に戻るまで待機する必要がありますが、待機にはまだ時間がかかります。待機中、CPU はファイル記述子を反復処理するか、時間が発生するまでスリープするために使用されます。
現実的な非同期 I/O
一部のスレッドにブロッキング I/O またはノンブロッキング I/O とポーリング テクノロジを実行させ、スレッドが実行できるようにすることでデータ取得を完了します。計算を実行し、スレッド間の通信を通じて I/O から取得したデータを転送します。これにより、非同期 I/O が簡単に実装されます (ただし、これはシミュレートされています)
しかし、当初、ノードは *nix にありました。プラットフォームは libeio と libev を使用して実装しますI/O 部分を実装し、非同期 I/O を実装します。 Node v0.9.3 では、非同期 I/O を完了するためにスレッド プールが実装されています。
Windows の IOCP は、非同期メソッドの呼び出し、I/O 完了後の通知の待機、コールバックの実行など、Li Xiang の非同期 I/O をある程度提供します。ユーザーはポーリングを考慮する必要はありません。ただし、その内部は依然としてスレッド プールの原則に基づいており、異なるのは、これらのスレッド プールがシステム カーネルによって管理されることです。
Windows プラットフォームと *nix プラットフォームの違いにより、Node は抽象カプセル化層として libuv を提供するため、すべてのプラットフォーム互換性の判断はこの層によって完了し、上位ノードと下位ノードのカスタマイズが保証されます。スレッド プールと IOCP は完全に独立しています。
Node はシングルスレッドであるとよく言いますが、ここでのシングルスレッドとは、単一のスレッドで実行される JavaScript のことです。 Node には、*nix であっても Windows プラットフォームであっても、内部で I/O タスクを完了するスレッド プールがあります。
ノードの非同期 I/O
イベント ループ、オブザーバー、およびリクエスト オブジェクトにより、非同期 I/O リンク全体が完成します。
イベント ループ
イベント ループは Node 独自の実行モデルであり、コールバック関数が非常に一般的になります。
プロセスが開始されると、Node は while(true) に似たループを作成します。ループ本体が実行されるたびに、それを Tick と呼びます。各 Tick のプロセスは、処理対象のイベントがあるかどうかを確認し、存在する場合はイベントとそれに関連するコールバック関数を取得します。関連するコールバック関数が存在する場合は、それらを実行します。次に、次のループに入り、処理するイベントがなくなった場合はプロセスを終了します。
オブザーバー
各イベント ループには 1 つ以上のオブザーバーがあり、監視するイベントがあるかどうかを判断するために使用されます。処理されるプロセスでは、これらのオブザーバーに処理するイベントがあるかどうかを尋ねます。
Node では、イベントは主にネットワーク リクエスト、ファイル I/O などから発生します。これらの時間に対応するオブザーバーには、ファイル I/O オブザーバー、ネットワーク I/O オブザーバーなどが含まれます。オブザーバーがイベントを分類しました。
イベント ループは、典型的なプロデューサー/コンシューマー モデルです。非同期 I/O やネットワーク リクエストなどがイベントのプロデューサーであり、常にさまざまな種類のイベントを Node に提供し、これらのイベントは対応するオブザーバーに配信され、イベント ループはオブザーバーからイベントを取り出して処理します。
リクエスト オブジェクト
ノードの非同期 I/O 呼び出しの場合、コールバック関数は開発者によって呼び出されません。呼び出しを開始する JavaScript から I/O 操作を実行するカーネルへの移行プロセスでは、Request オブジェクト
という製品があり、以下では fs.open() メソッドが小さな例。
fs.open = function(path,flags,mode,callback){ //... binding.open(pathModule._makeLong(path), stringToFlags(flags), mode, callback); }
fs.open() の機能は、指定されたパスとパラメータに基づいてファイルを開き、ファイル記述子を取得することです。これは、後続のすべての I/O 操作に対する最初の試行操作です。 JavaScript レベルのコードは、C コア モジュールを呼び出すことによって下位レベルの操作を実行します。
は、Node のコア モジュールを呼び出す JavaScript に取り組んでいます。コア モジュールは C モジュールを呼び出し、組み込みモジュールは libuv を通じてシステム コールを行います。これは古典的なものです。 Node でメソッドを呼び出します。ここで、libuv はカプセル化層として機能し、基本的に uv_fs_open() メソッドを呼び出す 2 つのプラットフォーム実装があります。 uv_fs_open() の呼び出しプロセス中に、JavaScript レイヤーから渡されたパラメーターと現在のメソッドがリクエスト オブジェクトにカプセル化され、コールバック関数がこのオブジェクトのプロパティに設定されます。オブジェクトがパッケージ化された後、オブジェクトはスレッド プールにプッシュされて実行を待ちます。
この時点で、JavaScript 呼び出しはすぐに戻り、JavaScript レベルによって開始された非同期呼び出しの最初のフェーズが終了します。 JavaScript スレッドは、現在のタスクに対して後続の操作を実行し続けることができます。
リクエスト オブジェクトは、非同期 I/O プロセスの重要な中間生成物です。I/O 操作の完了後の実行とコールバック処理を待機するためにスレッド プールに送信される状態を含む、すべての状態がこのオブジェクトに保存されます。
実行コールバック
リクエスト オブジェクトをアセンブルし、I/O スレッド プールに送信して実行を待機します。これは I/O の最初の部分のみを完了しますコールバック通知は最初の部分であり、その 2 です。
スレッド プール内の I/O 操作が呼び出された後、取得された結果は req->result 属性に格納され、PostQueueCompletionStatus() が呼び出されて、現在のオブジェクト操作が IOCP に通知されます。完成しました。
この時点で、非同期 I/O プロセス全体が完全に終了しました。
イベント ループ、オブザーバー、リクエスト オブジェクト、および I/O スレッド プールは、一緒になってノードの非同期 I/O モデルの基本要素を構成します。
まとめ
整理すると、非同期 I/O のキーワードとして、シングル スレッド、イベント ループ、オブザーバー、I/O スレッド プールがいくつか抽出できます。シングルスレッドとスレッドプールは少し矛盾しているように思えます。 JavaScript はシングルスレッドであるため、マルチコア CPU を最大限に活用できないことは容易に理解できます。実際、Node では、JavaScript がシングルスレッドであることを除いて、Node 自体は実際にはマルチスレッドですが、I/O スレッドが使用する CPU は少なくなります。また、ユーザーコードは並列実行できないことを除き、すべての I/O (ディスク I/O、ネットワーク I/O など) は並列実行できます。
プログラミング関連の知識について詳しくは、プログラミング ビデオをご覧ください。 !
以上がNodejs の非同期 I/O についての予備的な理解の詳細内容です。詳細については、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)

ホットトピック









Node.js は、高いパフォーマンス、スケーラビリティ、クロスプラットフォーム サポート、豊富なエコシステム、開発の容易さなどの機能を備えているため、バックエンド フレームワークとして使用できます。

MySQL データベースに接続するには、次の手順に従う必要があります。 mysql2 ドライバーをインストールします。 mysql2.createConnection() を使用して、ホスト アドレス、ポート、ユーザー名、パスワード、データベース名を含む接続オブジェクトを作成します。 connection.query() を使用してクエリを実行します。最後に connection.end() を使用して接続を終了します。

Node.js には次のグローバル変数が存在します。 グローバル オブジェクト: グローバル コア モジュール: プロセス、コンソール、require ランタイム環境変数: __dirname、__filename、__line、__column 定数: unknown、null、NaN、Infinity、-Infinity

Node.js インストール ディレクトリには、npm と npm.cmd という 2 つの npm 関連ファイルがあります。違いは次のとおりです。拡張子が異なります。npm は実行可能ファイルで、npm.cmd はコマンド ウィンドウのショートカットです。 Windows ユーザー: npm.cmd はコマンド プロンプトから使用できますが、npm はコマンド ラインからのみ実行できます。互換性: npm.cmd は Windows システムに固有ですが、npm はクロスプラットフォームで使用できます。使用上の推奨事項: Windows ユーザーは npm.cmd を使用し、他のオペレーティング システムは npm を使用します。

Node.js と Java の主な違いは、設計と機能です。 イベント駆動型とスレッド駆動型: Node.js はイベント駆動型で、Java はスレッド駆動型です。シングルスレッドとマルチスレッド: Node.js はシングルスレッドのイベント ループを使用し、Java はマルチスレッド アーキテクチャを使用します。ランタイム環境: Node.js は V8 JavaScript エンジン上で実行され、Java は JVM 上で実行されます。構文: Node.js は JavaScript 構文を使用し、Java は Java 構文を使用します。目的: Node.js は I/O 集中型のタスクに適しており、Java は大規模なエンタープライズ アプリケーションに適しています。

はい、Node.js はバックエンド開発言語です。これは、サーバー側のビジネス ロジックの処理、データベース接続の管理、API の提供などのバックエンド開発に使用されます。

Node.js プロジェクトのサーバー デプロイメント手順: デプロイメント環境を準備します。サーバー アクセスの取得、Node.js のインストール、Git リポジトリのセットアップ。アプリケーションをビルドする: npm run build を使用して、デプロイ可能なコードと依存関係を生成します。コードをサーバーにアップロードします: Git またはファイル転送プロトコル経由。依存関係をインストールする: サーバーに SSH で接続し、npm install を使用してアプリケーションの依存関係をインストールします。アプリケーションを開始します。node Index.js などのコマンドを使用してアプリケーションを開始するか、pm2 などのプロセス マネージャーを使用します。リバース プロキシの構成 (オプション): Nginx や Apache などのリバース プロキシを使用して、トラフィックをアプリケーションにルーティングします。

Web 開発において Node.js と Java にはそれぞれ長所と短所があり、どちらを選択するかはプロジェクトの要件によって異なります。 Node.js はリアルタイム アプリケーション、迅速な開発、マイクロサービス アーキテクチャに優れており、Java はエンタープライズ グレードのサポート、パフォーマンス、セキュリティに優れています。
