私は epoll の edge-mode を試しています。これは明らかに読み取り/書き込みの準備が整ったファイルのみを通知します (既に準備ができているか準備ができているかに関係なく、すべての準備ができているファイルを通知する level-mode とは対照的です)。
まず、システムを明確に把握しましょう。システムがどのように機能するかについての正確なメンタル モデルが必要です。あなたの見解epoll(7)
はあまり正確ではありません。
エッジ トリガーとレベル トリガーの違いは、イベントを正確に作成するものの定義です。前者は、ファイル記述子でサブスクライブされたアクションごとに 1 つのイベントを生成します。イベントを消費すると、そのイベントを生成したすべてのデータを消費しなくても、イベントはなくなります。OTOH、後者は、イベントを生成したすべてのデータを消費するまで、同じイベントを何度も生成し続けます。
これらの概念を実行に移す例を次に示しますman 7 epoll
。
パイプ (rfd) の読み取り側を表すファイル記述子は、epoll インスタンスに登録されます。
パイプライターは、パイプの書き込み側に 2 kB のデータを書き込みます。
epoll_wait(2) への呼び出しが行われ、rfd が準備完了のファイル記述子として返されます。
パイプ リーダーは、rfd から 1 kB のデータを読み取ります。
epoll_wait(2) への呼び出しが行われます。
EPOLLET (エッジ トリガー) フラグを使用して rfd ファイル記述子が epoll インターフェースに追加されている場合、ステップ 5 で行われた epoll_wait(2) への呼び出しは、ファイル入力バッファーに利用可能なデータがまだ存在するにもかかわらず、ハングする可能性があります。一方、リモート ピアは、すでに送信したデータに基づいた応答を期待している可能性があります。これは、監視対象のファイル記述子で変更が発生した場合にのみ、エッジ トリガー モードがイベントを配信するためです。したがって、ステップ 5 で、呼び出し元は、入力バッファー内に既に存在するデータを待機することになる可能性があります。上記の例では、2 で行われた書き込みのために rfd のイベントが生成され、イベントは 3 で消費されます。4 で行われた読み取り操作はバッファ データ全体を消費しないため、epoll_wait(2) の呼び出しが行われます。手順 5 では、無期限にブロックされる可能性があります。
つまり、根本的な違いは「イベント」の定義にあります。エッジ トリガーでは、イベントを 1 回消費する単一のユニットとして扱います。level-triggered は、イベントの消費が、そのイベントに属するすべてのデータの消費と同等であると定義します。
さて、それで、具体的な質問に取り組みましょう。
エッジモードでは、epoll_waiting を行っていないときに発生する準備イベントが通知されますか?
はい、そうです。内部的には、カーネルは各ファイル記述子で発生した興味深いイベントをキューに入れます。これらは への次の呼び出しで返されるためepoll_wait(2)
、イベントが失われることはありません。まあ、保留中の他のイベントがあり、渡されたイベント バッファがepoll_wait(2)
それらすべてに対応できない場合、次の呼び出しでは正確ではないかもしれませんが、要点は、最終的にこれらのイベントが報告されるということです。
まだリアームされていないワンショット ファイルのイベントはどうなりますか?
繰り返しますが、イベントを失うことはありません。ファイル記述子がまだ再準備されていない場合、興味深いイベントが発生した場合、ファイル記述子が再準備されるまで、単にメモリ内のキューに入れられます。リアームされると、保留中のイベント (ディスクリプタがリアームされる前に発生したイベントを含む) は、次の呼び出しで報告されますepoll_wait(2)
(正確には次の呼び出しではないかもしれませんが、報告されます)。つまり、EPOLLONESHOT
イベント監視を無効にするのではなく、単にイベント通知を一時的に無効にします。
では、最後の epoll_wait は常にソケット S の準備ができていることを通知されるのでしょうか? S が #1 の場合 (つまり、再装備されていない場合) はどうなりますか?
上で述べたことを考えると、今ではかなり明確になっているはずです。はい、そうなります。イベントを失うことはありません。epoll は強力な保証を提供します。また、スレッドセーフであり、異なるスレッドで同じ epoll fd を待機し、イベント サブスクリプションを同時に更新できます。epoll は非常に強力で、時間をかけて学習する価値があります。