ホームページ >Java >&#&チュートリアル >Java での IO 再利用の詳細な図とテキストの説明
この記事は主に Java IO 再利用に関する関連知識を紹介するものであり、非常に優れており、必要な方は参考にしてください。
サーバーの同時処理機能については、次のものが必要です。このミリ秒以内に数百の異なる TCP 接続で受信されたすべてのメッセージは、タイムリーに処理できます。同時に、サーバー上には、メッセージの送受信が行われていない数十万の比較的非アクティブな接続が存在する可能性があります。ここ数秒で。同時に並行して発生する複数の接続を処理することを、略して同時実行性と呼びます。数万または数十万の接続を同時に処理することを高同時実行性と呼びます。サーバーの同時実行性プログラミングが追求するのは、物理リソースが最初に使い果たされるまで、CPU などのリソースの効率的な使用を維持しながら、無限数の同時接続を処理することです。 同時プログラミングモデル
には多くの実装があり、最も単純なものは「スレッド」にバンドルされており、1つのスレッドが1つの接続のライフサイクル全体を処理します。利点: このモデルは非常にシンプルで、複雑なビジネス シナリオを実装でき、同時にスレッドの数が CPU の数よりもはるかに多くなる可能性があります。しかし、スレッド数は無限に増やすことができないのはなぜでしょうか。スレッドがいつ実行されるかはオペレーティング システムのカーネル スケジューリング アルゴリズムによって決定されるため、スケジューリング アルゴリズムでは、特定のスレッドが 1 つの接続のみを処理できることは考慮されません。統一されたゲームプレイが採用されます。たとえタイム スライスが終了した場合でもスレッドを実行します。このスレッドを実行すると、スリープを続ける必要があります。このスレッドのウェイクアップとスリープの往復は、回数が少ない場合は安価ですが、オペレーティング システム内のスレッドの総数が多い場合は、この技術的なスケジューリングの損失がスレッドに影響を与えるため、コストが高くなります (増幅されます)。ビジネスコードが実行される時刻。たとえば、現時点で非アクティブな接続を持つスレッドのほとんどは、実行効率が低すぎるため、起動して CPU リソースを奪い合います。これは、アクティブな接続を処理するプライベート エンタープライズ スレッドの数が減少し、CPU を獲得する機会が減少することを意味します。CPU は競争力の中心であり、その非効率性は総 GDP スループットに影響します。私たちが追求しているのは、数十万の接続を同時に処理することです。数千のスレッドが出現すると、システムの実行効率は高い同時実行性を満たせなくなります。 同時実行性の高いプログラミングには、現在モデルが 1 つだけあり、それが本質的に唯一の効果的な方法です。接続上のメッセージ処理は、メッセージの準備ができるまで待機する段階とメッセージの処理という 2 つの段階に分けることができます。デフォルトのブロッキング ソケット (たとえば、前述の 1 つの接続を処理するためにバンドルされた 1 つのスレッド) を使用する場合、これら 2 つのステージは 1 つに結合されることが多いため、ソケット コードを操作するスレッドはメッセージの準備ができるまでスリープする必要があります。これにより、同時実行性が高い状態ではスレッドが頻繁にスリープおよびウェイクアップするため、CPU 使用効率に影響します。
同時実行性の高いプログラミング方法では、当然のことながら 2 つの段階を分離します。つまり、メッセージの準備ができるまで待機するコード セクションが、メッセージを処理するコード セクションから分離されます。もちろん、これにはソケットが非ブロッキングである必要もあります。そうでない場合、条件が満たされない場合、メッセージを処理するコード セグメントによってスレッドが簡単にスリープ待機段階に入る可能性があります。そこで問題は、メッセージの準備が完了するのを待つこの段階をどのように達成するかということです。結局のところ、まだ待機中です。つまり、スレッドはまだスリープ状態でなければなりません。解決策は、積極的にクエリ
を実行するか、1 つのスレッドがすべての接続を待機するようにすることです。これがIO多重化です。多重化はメッセージの準備ができるのを待つことですが、複数の接続を同時に処理できます。 「待機」することもできるため、スレッドがスリープ状態になる可能性もありますが、1 対多であり、すべての接続を監視できるため、これは問題ではありません。このようにして、スレッドが実行のために起動されると、コードによって実行される準備ができている接続がいくつか存在する必要があり、これは効率的です。 「メッセージの準備ができるのを待っている」フェーズの処理を競合するスレッドはそれほど多くなく、ついに全世界が明らかになりました。linux では、2.4 カーネル以前では、主に select と poll が実装されていましたが、その使用方法は大きく異なっているように見えますが、本質は同じです。
効率も異なるため、epoll は select を完全に置き換えました。 epoll が select を置き換える理由について簡単に説明しましょう。
前述したように、高い同時実行性を実現するための中心的な解決策は、すべての接続に対して 1 つのスレッドで「メッセージの準備ができるまで待機」することです。この点では、epoll と select には議論の余地がありません。しかし、記事の冒頭で述べたように、数十万の同時接続が存在する場合、アクティブな接続は 1 ミリ秒あたり数百しかなく、残りの数十万の接続はアクティブである可能性があります。このミリ秒間は非アクティブです。 select の使用方法は次のとおりです:
返されたアクティブな接続 ==select (監視対象のすべての接続)select メソッドはいつ呼び出されますか?パケットが到着したアクティブな接続を確認する必要があると考えられる場合は、これを呼び出す必要があります。したがって、同時実行性が高い場合、select の呼び出しは頻繁に呼び出されます。このように、この頻繁に呼び出されるメソッドが効率的であるかどうかを確認する必要があります。なぜなら、そのわずかな効率の低下が「頻繁」という言葉によって増幅されるからです。効率が低下することはありますか?明らかに、監視対象の接続は数十万件ありますが、返されるアクティブな接続は数百件のみであり、それ自体が非効率です。強化された後、select は数万の同時接続をまったく処理できないことがわかります。 いくつかの写真を見てください。同時接続数が 1,000 未満の場合、select の実行回数はそれほど多くなく、epoll と大きな違いはないようです:
削除)
返されたアクティブな接続 == epoll_wait (epoll 記述子) これを行う主な利点は、頻繁に呼び出される操作とあまり呼び出されない操作を区別できることです。たとえば、epoll_ctrl はそれほど頻繁には呼び出されませんが、epoll_wait は非常に頻繁に呼び出されます。現時点では、epoll_wait には入力パラメーターがほとんどなく、select よりもはるかに効率的です。また、同時接続が増加しても入力パラメーターの数が増加することはなく、カーネルの実行効率が低下します。 もちろん、一般的なアプリケーション シナリオでは、両者の間にパフォーマンスに大きな違いはありません。ET の利点として考えられるのは、epoll_wait の呼び出し回数が減り、シナリオによっては接続が解除されないことです。は必要ありません (このウェイクアップは epoll_wait リターンを指します)。しかし、上で述べた例のような場合は、単なるネットワークの問題ではなく、アプリケーション シナリオに関連している場合があります。もちろん、ほとんどのオープンソースフレームワークはETに基づいて書かれており、フレームワークに関しては純粋に技術的な問題を追求し、もちろん完璧を目指しています
以上がJava での IO 再利用の詳細な図とテキストの説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。