asio から得られる主な用途は、それが IO 完了ポート (略して iocp) の上に構築されていることです。それでは、iocp と の比較から始めましょうWaitForMultipleObjects()
。select
これらの 2 つのアプローチは、基本的にLinuxの場合と同じepoll
です。
WaitForMultipleObjects
iocp によって解決された主な欠点は、多くのファイル記述子でスケーリングできないことです。これは O(n) です。これは、受け取るイベントごとに完全な配列を再度渡すためであり、内部で WaitForMultipleObjects が配列をスキャンして、どのハンドルでトリガーするかを知る必要があります。
ただし、2 つ目の欠点があるため、これが問題になることはめったにありません。WaitForMultipleObjects()
には、待機できるハンドルの最大数に制限があります ( MAXIMUM_WAIT_OBJECTS
)。この制限は 64 オブジェクトです (winnt.h を参照)。この制限を回避するには、Event オブジェクトを作成し、複数のソケットを各イベントに関連付けて、64 個のイベントを待機します。
3 番目の欠点は、実際には微妙な "バグ" があることWaitForMultipleObjects()
です。イベントをトリガーしたハンドルのインデックスを返します。これは、単一のイベントのみをユーザーに通知できることを意味します。select
これは、イベントをトリガーしたすべてのファイル記述子を返す とは異なります。WaitForMultipleObjects
渡されたハンドルをスキャンし、イベントが発生した最初のハンドルを返します。
これは、10 個の非常にアクティブなソケットを待機している場合、ほとんどの場合、すべてのソケットでイベントが発生している場合、 に渡されたリストの最初のソケットにサービスを提供することに非常に大きな偏りが生じることを意味しWaitForMultipleObjects
ます。これは、関数が戻り、イベントが処理されるたびに、タイムアウトを 0 にして再度実行することで回避できますが、今回は、トリガーされたイベントの後の配列 1 の部分のみを渡します。すべてのハンドルが訪問されるまで繰り返し、すべてのハンドルと実際のタイムアウトで元の呼び出しに戻ります。
iocp はこれらの問題をすべて解決し、より一般的なイベント通知用のインターフェースも導入しています。これは非常に優れています。
iocp (したがって asio) を使用する場合:
- 関心のあるハンドルを繰り返す必要はありません。Windows に 1 回伝えるだけで、Windows はそれを記憶します。これは、多くのハンドルを使用すると、スケーリングが大幅に向上することを意味します。
- 待機できるハンドルの数に制限はありません
- すべてのイベントを取得します。つまり、特定のハンドルに対する偏りはありません
async_read
カスタムハンドルで使用するというあなたの仮定についてはわかりません。それをテストする必要があるかもしれません。ハンドルがソケットを参照している場合、それが機能すると思います。
スレッドの質問については; はい。複数のスレッドを使用している場合run()
、io_service
イベントは空きスレッドにディスパッチされ、より多くのスレッドでスケーリングされます。これは、スレッド プール API を備えた iocp の機能です。
要するに: asio または iocp は単に を使用するよりも優れたパフォーマンスを提供すると信じていWaitForMultipleObjects
ますが、そのパフォーマンスが向上するかどうかは、ハンドルの数とそれらがどれだけアクティブであるかに大きく依存します。