Node.js は内部的にスレッドに依存しているのに、なぜ本質的に高速なのでしょうか? 質問する

Node.js は内部的にスレッドに依存しているのに、なぜ本質的に高速なのでしょうか? 質問する

私は次のビデオを見ました:Node.js 入門速度のメリットをどうやって得られるのかまだ理解していません。

主に、Ryan Dahl (Node.js の作成者) は、Node.js はスレッドベースではなくイベントループベースであると述べています。スレッドはコストがかかるため、並行プログラミングの専門家だけが利用すべきです。

その後、彼は、内部に独自のスレッド プールを持つ C 実装を基盤とする Node.js のアーキテクチャ スタックを示します。したがって、Node.js 開発者が独自のスレッドを開始したり、スレッド プールを直接使用したりすることは明らかにありません...非同期コールバックを使用します。その点は理解できます。

私が理解できないのは、Node.js がまだスレッドを使用しているという点です...実装を隠しているだけなので、50 人が 50 個のファイル (現在メモリ内にない) を要求した場合に、どのように高速化されるのでしょうか。50 個のスレッドが必要なのではないですか?

唯一の違いは、内部的に管理されるため、Node.js 開発者はスレッドの詳細をコーディングする必要がないが、その裏では IO (ブロッキング) ファイル要求を処理するためにスレッドが使用されていることです。

つまり、実際には 1 つの問題 (スレッド) を取り上げ、その問題 (主に複数のスレッド、コンテキストの切り替え、デッドロックなど) がまだ存在している間は、それを隠しているだけではないでしょうか。

ここではまだ理解していない詳細がいくつかあるはずです。

ベストアンサー1

実際には、ここではいくつかの異なることが混同されています。しかし、スレッドは本当に難しいというミームから始まります。スレッドが難しい場合、スレッドを使用すると、1) バグのために壊れる、2) スレッドを可能な限り効率的に使用しない、という可能性が高くなります。(2) が、あなたが尋ねているものです。

彼が挙げた例の 1 つ、つまりリクエストが来て何らかのクエリを実行し、その結果を使って何かを行う例について考えてみましょう。これを標準的な手続き型で記述すると、コードは次のようになります。

result = query( "select smurfs from some_mushroom" );
// twiddle fingers
go_do_something_with_result( result );

入ってくるリクエストによって上記のコードを実行する新しいスレッドが作成された場合、query()実行中は何もしないスレッドがそこに存在します。(Ryan によると、Apache は元のリクエストを満たすために単一のスレッドを使用していますが、彼が言及しているケースでは nginx の方がパフォーマンスが優れています。なぜなら、そうではないからです。)

さて、あなたが本当に賢いなら、クエリを実行している間に環境が別の何かを実行できるように上記のコードを表現するでしょう。

query( statement: "select smurfs from some_mushroom", callback: go_do_something_with_result() );

基本的に、これが node.js が行っていることです。基本的には、言語と環境によって便利な方法でコードを装飾し、環境が何をいつ実行するかを賢く判断できるようにします。その意味では、node.js は非同期 I/O を発明したという意味では新しいものではありません (誰かがそのようなことを主張したわけではありませんが)。しかし、表現方法が少し異なるという点で新しいのです。

注: 環境が何をいつ実行するかについて賢くなることができると私が言うとき、具体的には、ある I/O を開始するために使用されたスレッドが、他の要求、または並列で実行できる計算を処理するために、または他の並列 I/O を開始するために使用できるようになることを意味します。(ノードが同じ要求に対してより多くの作業を開始できるほど洗練されているかどうかはわかりませんが、その考え方は理解できます。)

おすすめ記事