11

「接続ごとのスレッド」アプローチ(スレッドプールを使用)で複数の接続を処理する必要がある同時TCPサーバーを作成しています。私の疑問は、すべてのスレッドが異なるファイル記述子を取得するための最も最適な方法はどれかということです。

次の 2 つの方法が最も推奨されることがわかりました。

  1. すべての着信接続を処理し、それらの記述子をデータ構造 (例: a ) に格納するメイン スレッド。次に、すべてのスレッドがキューから fd を取得できます。accepts()queue
  2. Accept() はすべてのスレッドから直接呼び出されます( Unix Network Programming V1で推奨)

それぞれに私が見つけた問題:

  1. すべての fd を格納する静的データ構造は、スレッドが読み取る前にロック( ) する必要があるため、かなりの数のスレッドがまったく同じ瞬間に読み取りたい場合、どのくらいの時間が経過するかわかりません。全員が目標を達成するまで。mutex_lock
  2. 同時呼び出しに関連するThundering Herdaccept()の問題は、Linux ではまだ完全に解決されていないことを読んでいたので、アプリケーションを少なくともアプローチと同じくらい遅くする人工的な解決策を作成する必要があるかもしれません。 1.

ソース:

(アプローチ2について話しているいくつかのリンク:dos-the-thundering-herd-problem-exist-on-linux- anymore-およびそれについて見つけた1つの記事(古い):linux-scalability/reports/accept.html

そして、アプローチ1を推奨するSOの回答:can-i-call-accept-for-one-socket-from-several-threads-simultaneously


私はこの問題に非常に興味があるので、それについての意見をお待ちしております:)

4

1 に答える 1

6

リンクしたStackOverflow の回答で述べたように、accept() を呼び出す単一のスレッドがおそらく進むべき道です。あなたはロックに関する懸念について言及していますが、最近ではBoost.LockfreeIntel TBBなどでロックフリー キューの実装が利用できるようになっています。必要に応じてそれらのいずれかを使用できますが、条件変数を使用してワーカー スレッドをスリープ状態にし、新しい接続が確立されたときにそのうちの 1 つを起動することもできます。

于 2013-07-13T13:26:25.247 に答える