0

私は I/O Completion Ports を何年も前から聞いていましたが、一度も使用したことがないと言って前に付けておきます。私のバックグラウンドは主にselectpollepoll、およびWSAEventSelectですWaitForMulitpleObjects。次のテキストの I/O Completion Ports について根本的な誤解がある場合は、訂正してください。

仕事中のプロジェクトの一環として、クライアントがプラグインに接続し、TCP 経由でシミュレーションとの間でデータを送受信できるようにするプラグイン (DLL) をシミュレーションに開発する任務を負っています。プラグインはサーバーとして機能します。シミュレーションは、別の (イーサネットではない) インターフェイスの通信チャネルをシミュレートします。この特定のアプリケーションでは、チャネルごとに 1 つのソケットを持つことが理にかなっています。いくつのクライアントが存在するか、または各クライアントによっていくつのチャネル (ソケット) が開かれるかはわかりません。ただし、64 を超える可能性が十分にあり、それが異常に多くないこと、おそらくせいぜい 1000 未満であることはわかっています。

シミュレーションの重要な側面は、関数が呼び出されたときにのみプラグインが動作できることですtest_cycle。各テスト サイクル中に、次のことを行う必要があります。

  1. クライアントからの新しい接続を受け入れる
  2. ソケットからデータを受信し、シミュレーションに転送します
  3. シミュレーションからデータを受け取り、クライアントに転送します

64 を超えるソケットが存在する可能性があるため、(簡単に) WSAEventSelectandWSAWaitForMultipleEventsを使用して、ソケットを読み取れるかどうか、またはクライアントが正常に接続を終了したかどうかを確認することはできません。

そのため、これを行うことができる他の 2 つの方法を考えました。

  1. 各ソケットをノンブロッキングにします。が呼び出されるたびtest_cycleに、ソケットごとに最大量のデータを受信しようとして、すべてのソケットをループします。

  2. I/O Completion Port を使用して、ソケットから非同期受信を発行します。で、タイムアウトが示される ( ?)まで、パラメーターを に設定して呼び出しをtest_cycle繰り返します。受信が発生した場合は、テスト サイクルが終了するまで次の受信呼び出しを延期します。これにより、クライアントがサーバーにメッセージをスパム送信しても、無期限にループすることはありません(うまくいけば)。GetQueuedCompletionStatusdwMilliseconds0WAIT_TIMEOUTtest_cycle

シミュレーションへのインターフェイスはスレッドセーフではなく、データをシミュレーションに転送するために行う処理作業はほとんどないため、I/O 完了ポートにワーカー スレッドを使用するメリットはないと思います。 、ロックを実行してシミュレーション API を呼び出すだけです。ただし、各ソケットをポーリングする必要がないため、パフォーマンスが向上する場合があります。

この規模のアプリケーションでは、最大ソケット数が約 1000 未満、通常は 100 未満ですが、I/O Completion Ports を使用することで複雑さが増すことに、実際にメリットはあるのでしょうか?

4

1 に答える 1

0

これを行うことができると思います:
1) リスナー スレッドを構築します。接続ごとに、ソケットのコピーをスレッド プールに送信します。
2) リクエストを処理するためのスレッドのプールを構築します。

I/O Completion Ports を使用せずに、スレッド間の転送にパイプを使用していますが、パフォーマンスは非常に優れています。

リソースが枯渇しないように、管理限界を設定します。

于 2014-09-25T14:46:14.430 に答える