71

selectがfdリストをたどる必要があるという多くの比較を見てきましたが、これは遅いです。しかし、なぜepollはこれを行う必要がないのでしょうか?

4

2 に答える 2

125

これについては多くの誤った情報がありますが、本当の理由は次のとおりです。

典型的なサーバーは、たとえば 200 の接続を処理する場合があります。データの書き込みまたは読み取りが必要なすべての接続にサービスを提供し、さらに作業が必要になるまで待機する必要があります。待機中に、これら 200 の接続のいずれかでデータを受信した場合は中断する必要があります。

ではselect、カーネルは、接続ごとに 1 つずつ、200 の待機リストにプロセスを追加する必要があります。これを行うには、プロセスを待機リストに追加するための「サンク」が必要です。プロセスが最終的に起動したら、200 個の待機リストすべてからプロセスを削除し、それらのサンクをすべて解放する必要があります。

対照的に、epollでは、epollソケット自体に待機リストがあります。プロセスは、1 つのサンクのみを使用して、その 1 つの待機リストにのみ配置する必要があります。プロセスが起動したら、1 つの待機リストから削除する必要があり、1 つのサンクだけを解放する必要があります。

明確にするために、epollでは、epollソケット自体をこれらの 200 接続のそれぞれに接続する必要があります。ただし、これは、接続が最初に受け入れられたときに、接続ごとに 1 回行われます。そして、これは、接続が削除されるときに、接続ごとに 1 回破棄されます。対照的に、selectそのブロックへの各呼び出しは、監視されているすべてのソケットのすべての待機キューにプロセスを追加する必要があります。

皮肉なことにselect、最大のコストは、アクティビティのないソケットにアクティビティがあったかどうかを確認することです。では、アクティビティがあった場合、そのアクティビティが発生したときにソケットにepoll通知されているため、アクティビティのないソケットをチェックする必要はありません。epollある意味では、select呼び出すたびに各ソケットをポーリングして、ソケットのアクティビティ自体がプロセスに通知するようにリギングしselectながらアクティビティがあるかどうかを確認します。epoll

于 2013-06-28T01:08:52.853 に答える
27

との主な違いは、epoll待機するファイル記述子のリストには 1 回の呼び出しの間だけ存在し、呼び出し元のタスクは 1 回の呼び出しの間だけソケットの待機キューに留まるということです。一方、 では、待機したい他の複数のファイル記述子からのイベントを集約する単一のファイル記述子を作成するため、監視対象の fd のリストは長く続き、タスクは複数のシステム コールにわたってソケット待機キューに留まります。 . さらに、fd は複数のタスク間で共有できるため、待機キュー上の単一のタスクではなく、それ自体が別の待機キューを含む構造であり、現在待機しているすべてのプロセスを含みます。selectselect()select()epollepollepollfd。void*(実装に関しては、これは、関数ポインタとその関数に渡すデータ ポインタを保持するソケットの待機キューによって抽象化されます)。

そのため、メカニズムをもう少し説明すると、次のようになります。

  1. epollファイル記述子には、struct eventpollこの fd に接続されている fd を追跡するプライベートがあります。また、現在この fdで実行struct eventpoll中のすべてのプロセスを追跡する待機キューもあります。また、現在読み取りまたは書き込みに使用できるすべてのファイル記述子のリストもあります。epoll_waitstruct epoll
  2. epollを使用して fd にファイル記述子をepoll_ctl()追加epollするstruct eventpollと、その fd の待機キューに が追加されます。また、fd が現在処理の準備ができているかどうかもチェックし、そうであれば、準備完了リストに追加します。
  3. epollを使用して fd を待機するepoll_waitと、カーネルは最初に準備完了リストをチェックし、ファイル記述子の準備が整っている場合はすぐに戻ります。そうでない場合は、 内の単一の待機キューに自身を追加し、struct eventpollスリープ状態になります。
  4. epoll()ed中のソケットでイベントが発生すると、epollコールバックが呼び出され、ファイル記述子が準備完了リストに追加され、現在そのソケットで待機しているすべてのウェイターも起動しますstruct eventpoll

struct eventpoll当然のことながら、さまざまなリストや待機キューに対して慎重にロックする必要がありますが、それは実装の詳細です。

注意すべき重要なことは、上記のどの時点でも、対象のすべてのファイル記述子をループするステップについて説明していないことです。完全にイベントベースであり、長時間続く fd のセットと準備完了リストを使用することにより、epoll は操作に O(n) 時間かかることを回避できます。ここで、n は監視されているファイル記述子の数です。

于 2014-04-21T13:29:26.770 に答える