selectが読み取りの準備ができていることを返した後、recv()を呼び出すのを待った後、非ブロッキングソケットでrecv()を呼び出すのとブロッキングソケットでrecv()を呼び出すのとの違いがわかりません。とにかく、この状況ではブロッキングソケットが決してブロックされないように思えます。
また、ノンブロッキング ソケットを使用するモデルの 1 つは、select のようなものを使用する代わりに、一定の時間が経過した後に呼び出し (recv/send/etc) を試みることだと聞きました。この手法は、select のようなものを使用する場合と比較すると、遅くて無駄に思えます (ただし、上記のように非ブロッキングの目的がまったく得られません)。これは、今日のネットワーク プログラミングでは一般的ですか?
4 に答える
The C10K Problemと呼ばれる大量の I/O を実行するためのさまざまなオプションすべての優れた概要があります。少なくとも 2006 年の時点では、多くのさまざまなオプションについてかなり完全な調査が行われています。
select
非ブロッキングソケットでの使用のトピックについて、それから引用します。
注: カーネルからの準備完了通知はヒントにすぎないことを覚えておくことは特に重要です。ファイル記述子から読み取ろうとすると、ファイル記述子の準備ができていない可能性があります。そのため、準備完了通知を使用する場合は非ブロッキング モードを使用することが重要です。
はい、ノンブロッキング ソケットを使用して、何も準備ができていない場合に待機するループを作成することもできますが、これは、select
または最新の代替品 ( epoll
、kqueue
、など) のいずれかを使用する場合に比べてかなり無駄です。誰もが実際にこれをやりたがる理由が思いつきません。同様のオプションはすべてselect
タイムアウトを設定する機能を備えているため、一定時間後に起動して通常のアクションを実行できます。ビデオ ゲームの実行など、かなり CPU を集中的に使用することを行っている場合、ノンブロッキング ソケットを使用して I/O を定期的にチェックしながら、スリープせずにコンピューティングを続けたいと思うかもしれません。
、 、 、 などのselect
機能はpoll
、複数のソケット/ファイル記述子の処理シナリオを対象としています。何百ものソケットが同時に接続されている高負荷の Web サーバーを想像してみてください。すべてをブロックすることなく、いつどのソケットから、どのソケットから出入りするかをどのように知ることができますか?epoll
kqueue
read
read
ノンブロッキング ソケットで呼び出した場合、 への最後の呼び出し以降にデータが受信されていない場合は、すぐに返されread
ます。しかなくread
、データが利用可能になるまで待機したい場合は、ビジー待機する必要があります。これにより、CPU が浪費されます。
poll
そしてselect
(そして友達)読み取る(または書き込む、または信号を受信するなど)データがあるまでスリープすることができます。
そのソケットで送受信することだけを行う場合は、ノンブロッキング ソケットを使用することもできます。GUI の更新や他のソケットの処理など、その間に他にやるべきことがあるときは、非同期であることは重要です。
最初の質問については、そのシナリオに違いはありません。唯一の違いは、読み取るものが何もない場合の動作です。recv() を呼び出す前に確認しているので、違いはありません。
2 番目の質問については、データが利用可能かどうかをテストするために select、poll、epoll、kqueue を使用する方法がすべてのライブラリで行われていることがわかりました。select メソッドは最も古く、パフォーマンスの観点から (特に多数の接続を管理する場合) 最も望ましくありません。