1

私は、UNIXからWindowsへの比較的単純なネットワークコードの移植に取り組んでいます。

簡単に言うと、すべてのネットワークトラフィックを管理する単一のネットワークスレッドがあります。この単一のスレッドはpoll()ほとんどの場合内部にあり(Windowsではすでにこれをselect()に変換しています)、ネットワークスレッドは着信ネットワークデータがある場合にのみウェイクアップします。クライアントコマンドが到着すると、ネットワークスレッドは、バックエンドで実際に作業を実行するためにワーカースレッドにコマンドを起動し、さらに着信コマンドのリッスンに戻ります。コマンドは非同期です。1つのソケットに複数のコマンドを次々と入力できます。いつでも、1つの接続に数十の未処理のコマンドが存在する可能性があり、すべてがさまざまなワーカースレッドで処理されます。

poll()問題は、ワーカースレッドが応答データを送信しようとしているときに、ワーカースレッドが結果を送信しようとしているときに、ネットワークスレッドが内部でスリープしている可能性があることです。poll()ネットワークスレッドは、送信するためにキューに入れられた新しいアウトバウンドデータがあることに気付く前に、タイムアウト(または受信される別のパケット)を待つ必要があります。

UNIXでは、監視対象の記述子の中にパイプを含めることでこれに対処しpoll()ます。ワーカースレッドに送信するアウトバウンドデータがある場合は、パイプに1バイトのデータを書き込んでネットワークスレッドをウェイクアップします。しかし、WinSockはソケットの待機のみをサポートしているように見えるので、そのアプローチはWindowsでは機能しません。WinSockを使用してWindowsでこのアーキテクチャを救済する方法はありますか(異なるプラットフォーム間でほとんどのコードを共有できるようにするため)、またはWindowsで使用するカスタムネットワークサーバー実装を作成する以外に選択肢はありませんか?

アドバイスありがとうございます!

4

2 に答える 2

1

可能性は2つだけであり、どちらも提案しているソリューションを必要としません。

1)すでにこの接続でデータを送信しようとしていて、OSの送信キューがいっぱいです。この場合、selectまたはを中止する必要はありませんpoll。とにかく、現在接続に書き込むことはできません。できるだけ早く終了selectするか、自動的に終了します。poll

2)現在、この接続でデータを送信しようとしていません。selectこの場合、またはを中止する必要もありませんpoll。今すぐワーカースレッドにデータを書き込んでください。(ソケットはノンブロッキングですよね?)すべてのデータを書き込まない場合は、OSの送信キューがいっぱいであるためにのみ発生します。この場合、通常、書き込みを急ぐ必要はありません(適切なタイムアウトを設定します。select電話)。

selectただし、実際にはWindowsでは使用しないでください。これは、互換性のための大まかなハックとしてのみ提供される忌まわしいものです。Windowsを「本当に」サポートすることを計画している場合は、それを2番目のクラスにするべきではありません。ネットワークI/Oは、実際にはプラットフォーム固有でなければならないものです。

于 2012-11-01T05:27:55.207 に答える
0

Windowsで使用する代わりに、selectIO完了ポートとポストされた読み取りバッファーを使用すると、著しく良い結果が得られます。IOCPモデルでは、PostQueuedCompletionStatusAPIを使用してIOCPにサービスを提供しているスレッドと通信することができます。

于 2012-11-04T05:04:29.320 に答える