質問

Epoll ManPageによると、Epollet(エッジトリガー)に登録されたFDは、読み取りが行われていない場合、2回エポリンに通知すべきではないと述べています。
したがって、エポリンの後、Epoll_waitが新しいデータに新しいエポリンを返すことができる前に、バッファを空にする必要があります。

しかし、手つかずのFDSのエポリンイベントが複製されているのが見られるので、このアプローチで問題が発生しています。
これはStraceの出力であり、0x200はepollrdhupであり、私のglibcヘッダーではまだ定義されていませんが、カーネルで定義されています。

30285 epoll_ctl(3, EPOLL_CTL_ADD, 9, {EPOLLIN|EPOLLPRI|EPOLLERR|EPOLLHUP|EPOLLET|0x2000, {u32=9, u64=9}}) = 0
30285 epoll_wait(3, {{EPOLLIN, {u32=9, u64=9}}}, 10, -1) = 1
30285 epoll_wait(3, {{EPOLLIN, {u32=9, u64=9}}}, 10, -1) = 1
30285 epoll_wait(3,  <unfinished ...>
30349 epoll_ctl(3, EPOLL_CTL_DEL, 9, NULL) = 0
30306 recv(9, "7u\0\0\10\345\241\312\t\20\f\32\r\10\27\20\2\30\200\10 \31(C0\17\32\r\10\27\20\2\30"..., 20000, 0) = 20000
30349 epoll_ctl(3, EPOLL_CTL_DEL, 9, NULL) = -1 ENOENT (No such file or directory)
30305 recv(9, " \31(C0\17\32\r\10\27\20\2\30\200\10 \31(C0\17\32\r\10\27\20\2\30\200\10 \31("..., 20000, 0) = 10011

したがって、FD番号9を追加した後、ファイル記述子をリクセントする前に2つの連続したエポリンイベントを受け取ります。SyscallTraceは、読み取り前にFDを削除する方法を示していますが、イベントごとに1回しか発生しません。
だから、私はマンページを適切に読んでいないか、ここで何かが機能しているかのどちらかです。

役に立ちましたか?

解決

この部分を逃したと思います epoll 男ページ:

エッジトリガーされたePollがあっても、複数のデータを受け取ると複数のイベントを生成できるため、発信者はを指定するオプションがあります。 EPOLLONESHOT フラグ、イベントの受領後に関連するファイル記述子を無効にするようにePollに伝えるために epoll_wait(2). 。いつ EPOLLONESHOT フラグが指定されています、それはファイル記述子を使用してリアルムするのは発信者の責任です epoll_ctl(2)EPOLL_CTL_MOD.

つまり、最初のキューの前に受信キューに2つのデータが到着しました read() 起こりました。つまり、2つのePollイベントがあります。のようです EPOLLONESHOT あなたが望んでいるものであり、イベントが発生したときに、ポーリングセットからファイル記述子を原子的に削除します(したがって、あなたはする必要はありません EPOLL_CTL_DEL).

他のヒント

Edgeトリガーは、(エポロンショットを使用していない限り)(カーネル)バッファーに入ると1つのイベントを取得することを意味します。

したがって、1つのエポリンイベントを取得してそれについて何もしない場合、次回その記述子にいくつかのデータが到着すると別のエポリンを取得します - 新しいデータが到着しない場合、たとえそうしなくてもイベントはありません最初のイベントで示されているように、データをお読みください。

まあ、それを簡潔に言えば、epolloneshotは、あなたが読むべきデータを読んでいない場合、それらは破棄されることを意味します。

通常、読んでいない場合、同じデータのイベントが通知されます。ただし、Epolloneshotでは、データを読み取らないことは完全に合法であり、無視されます。したがって、それ以上のイベントは生成されません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top