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 は正常に機能します。