3

Windows での非同期ソケット I/O のオプションを調査しています。明らかに複数のオプションがあります。完了コールバックまたはイベントのいずれかを提供するオーバーラップ構造で WSASend... を使用するか、IOCP と (新しい) スレッド プールを使用することができます。私が通常読んだものから、後者のオプションが推奨されます。

ただし、完了ルーチンが私の目標に十分な場合、IOCPを使用する必要がある理由は明確ではありません。ソケットにこのデータブロックを送信するように指示し、完了した場合は通知します。

などと組み合わせた IOCPCreateThreadpoolIoは、OS スレッド プールを使用することを理解しています。ただし、「通常の」オーバーラップ I/O も別のスレッドを使用する必要がありますか? では、違い/欠点は何ですか?私のコールバックは I/O スレッドによって呼び出され、他のものをブロックしていますか?

前もって感謝します、クリストフ

4

2 に答える 2

2

どちらも使用できますが、サーバーの場合、「完了キュー」を使用した IOCP は、CreateThreadpoolIo またはユーザー空間スレッド プールのいずれかを使用して複数の client<>server スレッドを使用できるため、一般にパフォーマンスが向上します。明らかに、この場合、専用のハンドラ スレッドが通常使用されます。

オーバーラップされた完了ルーチン I/O は、クライアントにとってより便利です。完了ルーチンは、I/O 要求を開始したスレッド (WSASend、WSARecv) のキューに入れられた非同期プロシージャ コールによって開始されます。これは、そのスレッドが APC を処理する位置にある必要があることを意味し、通常、これは、いくつかの 'blahEx()' 呼び出しを回避する while(true) ループを意味します。これは、スレッドが送信するデータを提供できるようにするブロッキング キューまたはその他のスレッド間シグナルを待機するのが非常に簡単であり、完了ルーチンが常にそのスレッドによって処理されるため、便利です。この I/O メカニズムにより、'hEvent' OVL パラメータを自由に使用できるようになります。通信バッファ オブジェクト ポインタを完了ルーチンに渡すのに理想的です。

実際の同期イベント/セマフォ/オーバーラップされた hEvent パラメーターを使用した I/O のオーバーラップは避ける必要があります。

于 2013-08-02T19:03:56.843 に答える
0

Windows IOCP のドキュメントでは、完了ポートごとに使用可能なコアごとに 1 つ以下のスレッドを推奨しています。ハイパースレッディングにより、コア数が 2 倍になります。IOCP を使用すると、実用的なイベント駆動型アプリケーションになるため、スレッド プールを使用すると、スケジューラに不要な処理が追加されます。

考えてみれば、その理由がわかるでしょう。イベントはできるだけ早く全体を処理する (または最初の処理後に何らかのキューに入れる) 必要があります。4 コア コンピューターの IOCP に 5 つのイベントがキューに入れられているとします。IOCP に 8 つのスレッドが関連付けられている場合、スケジューラが 1 つのイベントを中断して別のスレッドを使用して別のイベントの処理を開始する危険性がありますが、これは非効率的です。中断されたスレッドがクリティカル セクション内にある場合も危険です。4 つのスレッドを使用すると、4 つのイベントを同時に処理でき、1 つのイベントが完了するとすぐに、IOCP キューに残っている最後のイベントから開始できます。

もちろん、非 IOCP 関連の処理用にスレッド プールを使用することもできます。

編集__ _ __ _ _ __ _ _ _ _ _

ソケット (ファイル ハンドルも正常に動作します) は IOCP に関連付けられています。完了ルーチンは IOCP で待機します。要求されたソケットからの読み取りまたはソケットへの書き込みが OS を完了するとすぐに (IOCP を介して)、IOCP で待機している完了ルーチンを解放し、読み取りまたは書き込みを呼び出したときに提供した追加情報を返します (通常、ポインターをに渡します制御ブロック)。したがって、完了ルーチンは、完了に関連する情報を見つける場所をすぐに「認識」します。

制御ブロック (同様) を参照する情報を渡した場合、その制御ブロック (おそらく) は、次に何をすべきかを知るために、どの操作が完了したかを追跡する必要があります。IOCP 自体は、認識も気にもしません。

インターネットに接続されたサーバーを作成している場合、サーバーは読み取りを発行してクライアントの入力を待ちます。その入力は 1 ミリ秒または 1 週間後に到着する可能性があり、到着すると、IOCP は入力を分析する完了ルーチンをリリースします。通常、入力で要求されたデータを含む書き込みで応答し、IOCP を待機します。書き込みが完了すると、IOCP は書き込みが完了したことを確認する完了ルーチンを再び解放し、(通常) 新しい読み取りを発行し、新しいサイクルが開始します。

そのため、IOCP ベースのアプリケーションは通常、完了が発生するまで CPU をほとんど (またはまったく) 消費しません。この時点で、完了ルーチンが処理を完了するまで完全に傾き、新しい I/O 要求を送信して、完了ポートで再び待機します。 . IOCP タイムアウト (ハウスキーピングなどを通知するために使用できます) とは別に、すべての I/O 関連のものは OS で発生します。

さらに複雑 (または単純化) するために、WSA ルーチンを使用してソケットを処理する必要はありません。Win32 関数の ReadFile と WriteFile は正常に機能します。

于 2013-08-15T13:45:21.953 に答える