投票と選択の違いは何ですか?


回答:


90

これはあなたの質問に答えると思います:

Richard Stevens(rstevens@noao.edu)から:

基本的な違いは、select()のfd_setはビットマスクであるため、サイズが固定されていることです。カーネルがコンパイルされるときに、カーネルがこのサイズを制限しないことが可能であり、アプリケーションがFD_SETSIZEを必要に応じて定義できるようにします(システムヘッダーのコメントが示すとおり)。4.4BSDのカーネルとSolarisライブラリ関数には、この制限があります。しかし、BSD / OS 2.1はこの制限を回避するようにコード化されているので、プログラミングのほんの少しの問題で、実行可能です。:-)誰かがこれについてSolarisバグレポートを提出し、修正されるかどうかを確認する必要があります。

ただし、poll()を使用する場合、ユーザーはpollfd構造体の配列を割り当て、この配列のエントリ数を渡す必要があるため、基本的な制限はありません。Casperが指摘するように、poll()を持つシステムはselectよりも少ないため、後者の方が移植性が高くなります。また、元の実装(SVR3)では、記述子を-1に設定してカーネルにpollfd構造体のエントリを無視するように指示できなかったため、配列からエントリを削除することが困難でした。SVR4はこれを回避します。個人的には、常にselect()を使用し、ほとんどの場合poll()を使用しています。これは、コードをBSD環境にも移植するためです。これらの環境では、select()を使用するpoll()の実装を誰かが作成する可能性がありますが、私はこれを見たことはありません。select()とpoll()の両方がPOSIX 1003.1gによって標準化されています。

2017年10月の更新:

上記のメールは少なくとも2001年のものです。poll()BSDを含む-コマンドは現在(2017年)すべての近代的なオペレーティングシステムでサポートされています。実際、一部の人々はそれselect() を廃止すべきだと考えています。意見は別として、周りの移植性の問題poll()は、現代のシステムではもはや問題ではありません。さらに、epoll()manページを読むことができる)以降開発され、人気が高まっています。

最近の開発ではselect()、明示的に問題はないものの、おそらく使用したくないでしょう。 poll()、そしてそれはより近代的な進化でありepoll()select()その制限に悩まされることなく同じ機能(およびそれ以上)を提供します。


15
スティーブンスの回答はいつ書かれましたか?BSDで利用できないpoll()に関するコメントはまだ適用されますか?MacOS X(一部はBSDに基づいています)にはpoll()があり、POSIX標準(POSIX 2008)ではこれが必要です。
ジョナサンレフラー

12
リッチスティーブンスは1999年9月に亡くなりました。そのため、答えはそれよりも古くなければなりません。彼は1996年1月にリリースされたBSD / OS 2.1に新しい変更が見られたので、おそらくその頃に言及しています。
10

2
信じられない。5年前に投稿された回答、私はつまずきました。ブラウザで開いたままにしておきます。翌日、著者は回答を編集して改善します。SOは、AJAX / websocketを使用してページの更新を通知します。これがSOがすばらしい理由です
Steven Lu

9
AJAX /のWebSocketを使用しているかどうかにはい@StevenLuが、残念ながら何の言葉ないselectpoll:(
クリストファー・シュルツ

>誰かがこれらの環境のためにselect()を使用するpoll()の実装を書くことができましたが、私はこれを見たことはありません。Javaはそうする;-)
Sergey Mashkov 2017

229

このselect()呼び出しでは、3つのビットマスクを作成して、読み取り、書き込み、およびエラーを監視するソケットとファイル記述子をマークし、オペレーティングシステムは、実際に何らかのアクティビティがあったものにマークを付けます。poll()ディスクリプタIDのリストを作成し、オペレーティングシステムがそれらのそれぞれに発生したイベントの種類でマークを付けます。

このselect()方法はかなり不格好で非効率的です。

  1. 通常、プロセスで使用できる潜在的なファイル記述子は1,000以上あります。長時間実行するプロセスで開いている記述子が数個しかないが、そのうちの少なくとも1つに高い数が割り当てられている場合、渡されるビットマスクは、select()その最高の記述子に対応するのに十分な大きさである必要があるため、数百ビットの範囲全体がオペレーティングシステムがselect()呼び出しが設定されていないことを検出するためだけに、呼び出しごとにループする必要があることを設定解除します。

  2. select()戻ったら、呼び出し元は3つのビットマスクすべてをループして、発生したイベントを判別する必要があります。非常に多くの一般的なアプリケーションでは、常に1つまたは2つのファイル記述子だけが新しいトラフィックを取得しますが、3つのビットマスクすべてを最後まで読み取って、どの記述子であるかを見つける必要があります。

  3. オペレーティングシステムはビットマスクを書き換えることでアクティビティについて通知するため、ビットマスクは破壊され、リッスンするファイル記述子のリストでマークされなくなります。メモリに保持している他のリストからビットマスク全体を再構築するかmemcpy()、各select()呼び出し後に、各ビットマスクとデータブロックの重複コピーを台無しにしたビットマスクの上に保持する必要があります。

したがって、poll()同じデータ構造を再利用し続けることができるので、アプローチははるかにうまく機能します。

実際、今日のサーバーは一度に何万もの接続を処理することを望んでいるためpoll()、最近のLinuxカーネルのさらに別のメカニズムに影響を与えていepoll()ます。これは取り組みの良い紹介です:

http://scotdoyle.com/python-epoll-howto.html

このリンクには、次の利点を示す優れたグラフがありますepoll()select()この時点では、これらのグラフに線が表示されないほど非効率的で古臭いと見なされていることに注意してください!):

http://lse.sourceforge.net/epoll/index.html


更新:スタックオーバーフローの別の質問を次に示します。この質問の回答には、違いの詳細が含まれています。

Twistedでのselect / pollリアクターとepollリアクターの注意点


1
そして、Pythonでepollを使用する例にリンクするための+1-いくつかの興味深い例があるように見えます。それらを試してみる必要があります...
Allen George

答えを説明するための+1。epollについて言及しているがkqueueについては言及していない
グッドパーソン

この回答は、
epoll

0

どちらも遅く、ほとんど同じですが、サイズと機能の種類が異なります!

イテレータを書くとき、select毎回のセットをコピーする必要があります!ながら、pollこの種の問題を修正して美しいコードにしました。もう1つの違いは、pollデフォルトで1024を超えるファイル記述子(FD)を処理できることです。pollこの種のジョブを処理するための多くの変数を用意する代わりに、さまざまなイベントを処理してプログラムを読みやすくすることができます。とでの操作はpollselectチェックが多いため、線形で低速です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.