2012-10-07 1 views
5

私は、複数のクライアントからの同時読み込み/書き込み操作をサポートする必要のあるLinuxサーバーを作成しています。 選択機能を使用して、読み取り/書き込み可用性を管理したいと考えています。「選択」機能を持つ非ブロッキングソケットを使用する利点は何ですか?

これは私が理解できないことです:ソケットにデータが読み込まれるまで待機したいとします。 の選択のドキュメントでは、読み込み可能なデータがなくなるまでブロックされ、読み込み関数はブロックされないことが示されています。

selectを使用していて、読み取り機能がブロックされないことがわかっている場合、なぜソケットを非ブロックにする必要がありますか?

答えて

6

ソケットが準備完了状態であると報告されても、確認するまでに状態が変わることがあります。

良い例の1つは、接続を受け入れることです。新しい接続が到着すると、リスニングソケットは読み取りの準備として報告されます。 acceptを呼び出すまでに、何かを送信する前に、そしてacceptを呼び出す前に、相手側が接続を切断する可能性があります。もちろん、このケースの扱いはOSに依存しますが、新しい接続が確立されるまでacceptが単にブロックされる可能性があります。これにより、アプリケーションが他のソケットの処理を防ぐために無期限に待つことになります。リスニングソケットがノンブロッキングモードの場合、これは発生せず、EWOULDBLOCKなどのエラーが発生しますが、acceptはブロックされません。

いくつかのカーネルには、UDPでの興味深いバグ(select)がありました。データグラムが到着すると、selectはデータグラムが読み込みの準備ができているとマークされたソケットで起きます。データグラムチェックサム検証は、ユーザコードがrecvfrom(またはUDPデータグラムを受信できる他のAPI)を呼び出すまで延期されます。コードがrecvfromを呼び出し、検証コードがチェックサムの不一致を検出すると、データグラムは単に破棄され、recvfromは次のデータグラムが到着するまでブロックされます。この問題を解決するパッチの1つ(問題の説明とともに)はhereです。

2

通常はあなたをブロックするソケットを読み込もうとすると、代わりにEWOULDBLOCKを取得するため、プログラミングエラーが発生する可能性があります。ソケット以外のオブジェクトの場合、正確なAPI動作は変更されることがあります。http://www.scottklement.com/rpg/socktut/nonblocking.htmlを参照してください。

+0

ああ、ありがとう。 :) – CaptainCodeman

1

これはすごくうまくいくが、そうではない。それらを非ブロッキングにする最も良い理由はブロックしないことです。

考えてみてください。 select()は読むべきことがあると伝えますが、あなたはどれくらいか分かりません。 2バイト、2,000とすることができます。ほとんどの場合、そこにあるデータをすべて廃棄してからselectに戻ると効率的です。だから、あなたはwhileループを読んで入力してください

while (1) 
{ 
    n = read(sock, buffer, 200); 
    //check return code, etc 
} 

何も残っていないときに最後に何が起こったのですか?ソケットがブロックされていない場合はブロックし、select()のポイントを(少なくとも部分的に)破ります。

3

他の人が触れたカーネルのバグ以外にも、ノンブロッキングソケットを選択する別の理由は、ポーリングループであっても、高速に到着するデータでより優れたパフォーマンスが得られるからです。ブロッキングソケットが「読み取り可能」とマークされているときに何が起こるかを考えてください。どのくらいのデータが到着したかわからないので、一度だけ安全に読むことができます。次に、イベントループに戻り、ポーラーがソケットがまだ読めるかどうかをチェックする必要があります。これは、ソケットの読み取り/書き込みのたびに少なくとも2つのシステムコールを2回実行する必要があることを意味します。つまり、安全であることを伝えるためにselectと読み取り/書き込み呼び出し自体です。

ノンブロッキングソケットの場合は、最初のメッセージの後に不要な呼び出しをスキップしてselectにすることができます。ソケットにselectによって読み取り可能とフラグが付けられている場合は、データを返す限り読み取り可能です。これにより、データの高速バースト処理が高速になります。

+0

ありがとう、非常に良い点、私は読んでしようとすると別の選択よりも速くなることを知らなかった。 – CaptainCodeman

関連する問題