2

次の戦略はうまく機能しているようです。

  • 受け入れられた要求をプログラムが処理する方法に関係なく、リスナー ソケットで非ブロッキングの accept() 呼び出しで単一のスレッド/プロセスを使用する。
  • 各プロセスでブロックする accept() 呼び出しで複数のスレッド/プロセスを使用する。接続が入ると、accept() が 1 つだけ起動されます。

うまく機能しないのは、コールバックで accept() を使用して各スレッド/プロセスのリスナー ソケットを監視する EPOLLIN です。これにより、すべてのスレッド/プロセスが起動しますが、実際に accept() を実行できるのは 1 つだけです。これは、accept() をブロックして、接続が入ってくると混乱を引き起こした昔のようなものです。

EPOLLIN を使用しているときに、単一のスレッド/プロセスのみを accept() にウェイクアップさせる方法はありますか? それとも、スレッドを使用して分離しただけで、ブロッキングの accept() を使用するように書き直す必要がありますか?

単一のスレッド/プロセスのみがaccept()を実行するオプションではありません。これは、各プロセスがaccept()を実行している唯一のデーモンであるかどうかを各プロセスが知る必要がない方法でプロセスをプールとして管理しようとしているからです。リスナーソケット。

4

2 に答える 2

2

EPOLLETorを使用して、新しい接続が発生したときにイベントEPOLLONESHOTによって 1 つのスレッドが起動されるようにする必要があります。処理スレッドは、 ( )を返すか、 ( )で手動でリセットするまでループで呼び出す必要があります。扱いました。EPOLLINacceptEAGAINEPOLLETepoll_ctlEPOLLONESHOT

一般に、複数のスレッドと epoll を使用する場合はEPOLLET、 またはを使用しますEPOLLONESHOT。そうしないと、イベントが発生したときに、それを処理するために複数のスレッドが起動され、それらが互いに干渉する可能性があります。せいぜい、別のスレッドがイベントを処理していることを理解するのに時間を浪費してから、再び待機するだけです。最悪の場合、デッドロックや破損が発生します。

于 2013-10-21T14:29:24.673 に答える
2

複数のソケットが同じ proto+address+port でリッスンしている場合はどうですか? これは Linux で実現できますSO_REUSERPORThttps://lwn.net/Articles/542629/ . 試したことはありませんが、実際のイベントを取得できるソケットは 1 つだけなので、epoll でも動作するはずです。

emptor の警告これは移植性のない、Linux 専用のソリューションです。SO_REUSEPORTリンクされた記事に詳述されているいくつかのバグ/機能にも苦しんでいます。

于 2013-10-21T14:17:15.360 に答える