2

epoll_wait()とリスナーソケットの間で次の相互作用が見られます。リスナー ソケットを作成するための一連のイベントは次のとおりです。

  1. 電話socket()
  2. 電話bind()
  3. 呼び出しfcntl()てノンブロッキングに設定
  4. epoll_ctl()_ EPOLL_CTL_ADD_EPOLLET | EPOLLONESHOT | EPOLLIN
  5. 電話listen()

epoll_wait()このソケットやその他のソケットを呼び出すバックグラウンド スレッドがあり、手順 4 と 5 の間に呼び出しが行われるEPOLLHUPと、リスナー ソケットのイベントが受信されます。シーケンスを次のように変更します。

  1. 電話socket()
  2. 電話bind()
  3. 呼び出しfcntl()てノンブロッキングに設定
  4. 電話listen()
  5. epoll_ctl()_ EPOLL_CTL_ADD_EPOLLET | EPOLLONESHOT | EPOLLIN

EPOLLINはこの問題を解決しますが、接続は確立されているが、リスナー ソケットのイベントが受信されないという誤ったエラーが表示されるようになりました。

代わりにレベルトリガーモードを使用できることは理解していますが、これをエッジトリガーモードで機能させたいと考えています。

問題が何であるかについて何か考えはありますか?

4

1 に答える 1

1

のセマンティクスは、ある記述子に対してEPOLLONESHOT通知がプルされると、その記述子で通知を再度有効にするためにwithepoll_wait()を呼び出す必要があるということです。したがって、パッシブ/リッスン ソケットで が通知を無効にしているという理由だけで、接続が失われている可能性があります。(一般に、特別な状況を除いて使用すべきではありません。コードに自動的に追加されるのは定型文でもブードゥー教でもありません。)epoll_ctl()EPOLL_CTL_MODEPOLLONESHOTEPOLLONESHOT

さらに、非ブロッキング エッジ トリガー セマンティクスでは、リッスンしているソケットが入力可能であるという通知で、エラーが報告さaccept()れるまでループで呼び出す必要があります。一度だけEAGAIN呼び出すと、他の接続がキューに残る可能性があり、さらに、新しい接続がそのキューに追加されるまで、別のエッジ トリガー イベントは発生しません。(つまり、が指定されていないか、次の への呼び出しの前に毎回記述子が再度有効になっていると仮定します。)accept()EPOLLINEPOLLONESHOTepoll_wait()

補遺 EPOLLONESHOTを排除することは確かに試してみる価値があります。とにかくなぜそれが必要なのですか?

于 2013-01-08T18:35:02.980 に答える