1

より大きなプロジェクトの一部であるTCPサーバーを実装しようとしています。基本的に、サーバーは任意の数のクライアント(32以上)とのTCP接続を維持し、サービスを要求するすべてのクライアントにサービスを提供できる必要があります。私たちのシナリオでは、クライアントがサーバーに接続されると、何らかの障害が発生しない限り(たとえば、クライアントを実行しているマシンが故障した場合)、接続を閉じることはなく、サービスを繰り返し要求すると想定されます。サーバー。他のすべてのクライアントの場合も同じです。つまり、それぞれがサーバーとの接続を維持し、トランザクションを実行します。

今、私は上記の機能を使用して実装しましたselect()berkelyソケットAPIのシステムコール。クライアントの数が少ない場合(たとえば10)は正常に機能します。ただし、16コアのマシンにサーバーを実装しているため、サーバーを可能な限り高いレベルにスケーリングする必要があります。そのために、私はさまざまなマルチスレッド設計手法(たとえば、クライアントごとに1つのスレッドなど)を調べました。私の意見では、スレッドプールの設計が最適です。実装しようとしたときに、いくつかの問題が発生しました。メインスレッドを指定して、任意の数の着信接続を受け入れ、各接続のファイル記述子をデータ構造に保存し、スレッドのプールがある場合、どのように取得しますか特定のクライアントがサービスを要求しているかどうかをポーリングするスレッド。設計は、クライアントがサーバーに接続し、サービスを取得した後に接続を閉じて、プールからスレッドを選択し、クライアントにサービスを提供してから、将来の接続処理のためにプールにプッシュするというシナリオでは十分に単純です。しかし、接続を維持し、サービスを断続的に要求する一連のクライアントにサービスを提供する必要がある場合、これを行うための最良のアプローチは何でしょうか。私は本当にこれで立ち往生しているので、すべての助けは大いに感謝されます。ありがとう。

4

2 に答える 2

2

CPUごとに1つのスレッドと1つの追加スレッドを使用して、pthreadを使用します。

追加のスレッド(メインスレッド)は、listen()システム呼び出しで新しい接続をリッスンし、accept()で新しい接続を受け入れ、現在接続数が最も少ないワーカースレッドを判別し、そのワーカーのロック/ミューテックスを取得しますスレッドの「保留中の接続」FIFOキューは、受け入れられた接続の記述子をワーカースレッドの「保留中の接続」FIFOキューに配置し、「キューの確認」通知(パイプの使用など)をワーカースレッドに送信します。

ワーカースレッドは「select()」を使用して、受け入れた接続とデータを送受信します。ワーカースレッドがメインスレッドから「キューの確認」通知を受信すると、「保留中の接続」FIFOキューのロック/ミューテックスを取得し、新しく受け入れられた接続を「fd_set」リストに追加します。

1024接続および16CPUの場合。1つのメインスレッドが新しい接続を待機し(ただし、多くの新しい接続を期待しないため、ほとんど何もしません)、16のワーカースレッドがそれぞれ平均64の接続を処理することになります。

于 2012-01-29T23:55:18.030 に答える
0

クライアントごとに1つのスレッドが、ほぼ確実に最適な設計です。新しい接続を待機する際には、常に少なくとも1つのスレッドがブロックされていることを確認してください。acceptつまり、受け入れが成功した後、最後のスレッドである場合は、続行する前に新しいスレッドを作成する必要があります。セマフォは、新しいリスニングスレッドを生成する必要性を追跡するための優れたプリミティブであることがわかりました。

于 2012-01-30T00:40:38.853 に答える