NODE.JS + Windows:内部を見てみましょう

非同期イベントプログラミングの原理を理解しているが、内部からの動作がわからないnode.jsプログラマー向けの記事。 「ループ」円の標準的な画像では不十分で、少なくともイベントのサイクルがフードの下にあるものを確認したい場合は、猫の下にいます。





制限



説明を簡単にするために、単純なファイルを開く操作、つまり fsモジュールから関数を開きます。 当然、このため、非常に多くが記事の範囲外にとどまりますが、認識の容易さと技術的な詳細の間で妥協する必要があります。



require('fs').open("c:\\1.txt", 'r', function onOpen(err, result){ console.log("Result: ", result); });
      
      







IOCP



Node.jsがWindowsでどのように機能するかを理解するには、IOCPテクノロジーを理解する必要があります。 入力/出力完了ポートは、Windowsで使用される非同期I / O操作を実行するために設計されたテクノロジーです。 このテクノロジーの主なオブジェクトは、CreateIoCompletionPort()関数を使用して作成されたIOCPポートであり、IOCPポートがオペレーティングシステムで作成されたイベントキューをカプセル化することに主に関心があります。 PostQueuedCompletionStatus()関数はイベントをキューに入れ、GetQueuedCompletionStatus()関数はイベントを取得します。 さらに、キューが空の場合、GetQueuedCompletionStatusを呼び出したスレッドは、最初のイベントが発生するまで中断されます。







初期化



ここで、例に直接進む前に、node.jsを初期化する際のいくつかのポイントを検討します。 起動時に、 イベントループを記述する特別な構造が作成されます。ループと呼びましょう。 他のフィールドの中でも、構造にはIOCPポートへのリンクと非同期要求カウンターが含まれています。 簡単にするために、整数変数req_countとして示します。 ループが初期化されると、IOCPポートが作成されます。



 iocp _handle= CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
      
      









次に、イベントループが開始されます。これについては後で説明します。



機能を開きます。



そして最後に、オープン関数自体のアルゴリズム。

最初に、 非同期要求を記述する構造が作成および初期化されます。fs_open_reqと呼びましょう。 onOpenコールバックへのリンク、パスとファイルアクセス修飾子、およびリクエストを説明するその他の情報を保存します。 さらに、構造にはクエリ結果またはそのリンクを保存するためのフィールドが含まれます。

次に、ループ構造内の非同期要求のカウンターが増加します。

第三に、ファイルが開かれる別のストリームが作成されます。 この場合、メインスレッドのnode.jsはopen関数から戻り、イベントループの次の反復に進みます。 ファイル1.txtは、オペレーティングシステムによって生成されたストリームで開かれます。 その記述子は、fs_open_req構造に書き込まれます。







第4に、ファイルを開いて必要なすべての操作を完了した後、生成されたストリームはPostQueuedCompletionStatus()を呼び出し、ファイルを開くイベントをIOCPキューに入れます。 さらに、PostQueuedCompletionStatusパラメーターの1つを介して、生成されたイベントにfs_open_req構造へのリンクが付加されます。







イベントのサイクル。



イベントループの入り口で、非同期リクエストのカウンターがチェックされます。 登録された要求がない場合、プログラムは終了します。 存在する場合、GetQueuedCompletionStatus()関数が呼び出され、次のイベントを返すか、イベントがない場合は、発生するまでスレッドを中断します。

1回の反復で、GetQueuedCompletionStatus関数は、ファイルを開くイベントと、それを使用してfs_open_req構造体へのリンクを返すイベントを返します。 次に、node.jsは非同期要求のカウンターを減らし、コールバックonOpenを開始し、ファイルを開いた結果をパラメーターとして渡します。







おわりに



実際、それがすべてです。 私は基本的な原則だけを示したかったので、多くのことを説明する必要がありました。 たとえば、ネットワークI / O操作はわずかに異なる方法で構成され、IOCP機能を最大限に活用します。 しかし、次回はそれを残しましょう。



All Articles