1

これは質問 14221339 の続きです。

epoll_wait()ループ内で実行されているスレッド プールがあります。

外部スレッドはepoll_ctl()、リスナーソケットを呼び出して追加します

(EPOLLET | EPOLLONESHOT | EPOLLIN).

スレッド プールに 1 つのスレッドしかない場合EPOLLIN、最初の (そして唯一の) 接続試行のイベントの受信に断続的に失敗します。スレッド プールを 2 つに増やすと、ほとんどの場合、EPOLLINイベントの受信に失敗します。

私の理解では、epoll API はスレッドセーフですが、この観察結果はそうでないことを示しているようです。

4

1 に答える 1

7

エッジトリガーセマンティクスでは、呼び出しのシーケンスが正しくないと、競合状態が発生する可能性があります。関連するシステムコールは3つあります。

  1. epoll_ctl()を使用して通知をアクティブ化します(EPOLLONESHOTが使用されている場合は再アクティブ化します)。
  2. 通知を受信するためのepoll_wait()。
  3. システム入力:エラーEAGAINまでループでread()/ recv()/ accept()。

この順序で(繰り返し)実行すると、#3と#1の間の競合が発生する可能性があります。つまり、EAGAINが返された後、epoll_ctl()が実行される前に、カーネルの入力イベントが発生した場合です。一般に、再アクティブ化はI/Oの前に実行する必要があります。

  1. epoll_ctl()を使用して通知をアクティブ化します(EPOLLONESHOTが使用されている場合は再アクティブ化します)。
  2. システム入力:エラーEAGAINまでループでread()/ recv()/ accept()。
  3. 通知を受信するためのepoll_wait()。

(明らかに、I / Oは非ブロッキングである必要があります。)

于 2013-01-09T15:53:36.540 に答える