web-dev-qa-db-ja.com

なぜ非ブロッキングまたはブロッキングソケットを使用する必要があるのですか?

最初に、どの州でどれが最高かを尋ねなければなりませんか?たとえば、リアルタイムMMORPGサーバー。ノンブロッキングソケットを使用する代わりにクライアントごとにスレッドを作成するとどうなりますか?または、すべてのノンブロッキングソケットを含む1つのスレッドを使用するとどうなりますか?利点を説明してくれますか?

38
deniz

あなたの質問はより長い議論に値しますが、答えはここにあります:

  • ブロッキングソケットを使用するということは、1つのスレッドで常に1つのソケットのみがアクティブになることを意味します(アクティビティの待機中にブロックするため)
  • 一般に、ブロッキングソケットの使用は、ノンブロッキングソケットよりも簡単です(非同期プログラミングはより複雑になる傾向があります)
  • 述べたように、ソケットごとに1つのスレッドを作成できますが、スレッドにはオーバーヘッドがあり、非ブロッキングソリューションと比較して非常に非効率的です。
  • ノンブロッキングソケットを使用すると、はるかに大量のクライアントを処理できます。1つのプロセスで数十万にまで拡張できますが、コードは少し複雑になります

ノンブロッキングソケット(Windows)では、いくつかのオプションがあります。

  • ポーリング
  • イベントベース
  • 重複したI/O

オーバーラップI/Oは、正しく理解して実装するための最も複雑なモデルであることを犠牲にして、最高のパフォーマンス(数千のソケット/プロセス)を提供します。

基本的には、パフォーマンスとプログラミングの複雑さの関係です。

[〜#〜] note [〜#〜]

スレッド/ソケットモデルの使用が悪い考えである理由のよりよい説明はここにあります:

Windowsでは、スケジューラがプロセッサ時間を受け取るべきスレッドと受け取らないスレッドを適切に判断できないため、多数のスレッドを作成するのは非常に非効率的です。これは、各スレッドのメモリオーバーヘッドと相まって、ソケット接続を処理する容量が不足するかなり前に、OSレベルでメモリ(スタックスペース)とプロセッササイクル(スレッド管理のオーバーヘッド)が不足することを意味します。 。

33
Mike Dinescu

almostおもちゃのプログラム以外のものについては、当然のことながらノンブロッキングソケットを使用する必要があると言って記録に残ります。

ソケットのブロックは深刻な問題を引き起こします:反対側のマシン(またはその接続の一部)がブロック呼び出し中に失敗した場合、コードはIPスタックのタイムアウトまでブロックされます。通常の場合、それは約2分であり、ほとんどの目的にはまったく受け入れられません。唯一の方法1 そのブロッキング呼び出しを中止することは、それを作ったスレッドを終了することです-しかし、スレッドを終了することは、それをクリーンアップし、割り当てたリソースを回収することは本質的に不可能なので、ほとんど常に受け入れられません。ノンブロッキングソケットを使用すると、必要な場合または必要に応じて呼び出しを中止することが簡単になります。without呼び出しを行ったスレッドに対して何かを行う.

ブロッキングソケットをうまく機能させることができますif代わりにマルチプロセスモデルを使用します。ここでは、接続ごとにまったく新しいプロセスを作成します。そのプロセスはブロッキングソケットを使用し、何か問題が発生した場合は、プロセス全体を強制終了します。 OSはプロセスからリソースをクリーンアップする方法を知っているため、クリーンアップは問題になりません。ただし、1)必要に応じてプロセスを強制終了するためのプロセスモニターが非常に必要です。2)プロセスの生成は、通常、ソケットを作成するよりもかなり高価です。それにもかかわらず、これは特に次の場合に実行可能なオプションになります。

  1. 一度に少数の接続を処理している
  2. 通常、各接続に対して広範な処理を行います
  3. ローカルホストのみを扱っているため、ローカルホストへの接続は高速で信頼性が高い
  4. 実行よりも開発の最適化に関心がある

1.まあ、技術的にはonly可能な方法ではありませんが、ほとんどの選択肢は比較的いです-より具体的には、問題があることを理解するためにコードを追加するまでに、その後、問題を解決します。おそらく、非ブロッキングソケットを使用する場合よりも多くの余分な作業を行っているでしょう。

11
Jerry Coffin