2

boost::asio を使用する C++ で記述されたアプリケーションがあります。ソケットでリクエストをリッスンし、リクエストごとに CPU バウンドの作業 (ディスクやネットワーク I/O なしなど) を実行し、レスポンスで応答します。

このアプリケーションはマルチコア システムで実行されるため、リクエストを並行して処理するために、コアごとに (少なくとも) 1 つのスレッドを用意する予定です。

ここで最善のアプローチは何ですか?考慮事項:

  • 固定サイズのスレッド プールが必要です (例: CPU ごとに 1 スレッド)
  • スレッド数よりも多くのリクエストが到着した場合は、それらをキューに入れる必要があります (おそらく、o/s ソケット レイヤーで?)

現在、サーバーはシングル スレッドです。

  • クライアントのリクエストを待ちます
  • リクエストを受信すると、作業を実行し、レスポンスを書き戻し、次のリクエストの待機を開始します

アップデート:

より具体的には、サーバーがビジー状態の場合に着信要求がキューに入れられるようにするには、どのメカニズムを使用すればよいですか? N 個のスレッド (コアごとに 1 個) 間で着信要求を分散するには、どのメカニズムを使用すればよいですか?

4

3 に答える 3

2

あなたがまだカバーしていないことを考慮すべきことがたくさんあるとは思いません。

それが本当に CPU バウンドである場合、コア数を超えてスレッドを追加しても、多くのリクエストがある場合を除いて、あまり役に立ちません。その場合、リッスン キューがニーズを満たしている場合と満たしていない場合があり、接続を受け入れて自分でキューに入れるスレッドをいくつか用意した方がよい場合があります。システムのリッスン バックログ値を確認し、スレッド数を少し試してみてください。

アップデート:

listen() には、要求された OS/TCP キューの深さを表す 2 番目のパラメーターがあります。OSの制限まで設定できます。それを超えて、システムノブで遊ぶ必要があります。私の現在のシステムでは 128 であるため、巨大ではありませんが、些細なことでもありません。システムをチェックして、デフォルトよりも大きなものが実際に必要かどうかを検討してください。

それを超えて、あなたが行くことができるいくつかの方向があります。KISS を考えてみてください。実際に必要になる前に複雑なことはありません。接続を受け入れる (ある程度の制限まで) スレッドを用意し、それらをキューに配置するなど、簡単なことから始めます。ワーカー スレッドはそれらを取得し、処理し、結果を書き込み、ソケットを閉じます。

私のディストリビューションの Boost アップデートの現在のペース (および自分でコンパイルする意志の欠如) では、ASIO でプレイするのは 2012 年になるでしょう。

于 2009-07-22T20:33:45.367 に答える
1

エース http://www.cs.wustl.edu/~schmidt/ACE/book1/

必要なものがすべて揃っています。スレッド管理とキュー、および追加のボーナスとして、ソケット サーバーを記述するポータブルな方法。

于 2009-07-22T20:33:20.657 に答える
1

basic_socket_acceptor のオーバーロードされたコンストラクターを使用して特定のエンドポイントをバインドしてリッスンする場合、listen() の呼び出しで保留中の接続のバックログとして SOMAXCONN を使用します。これは Windows では 250 にマップされると思います (よくわかりません)。そのため、ネットワーク サービス プロバイダーは、この制限までクライアント接続を (黙って) 受け入れ、アプリケーションが処理できるようにそれらをキューに入れます。次の受け入れ呼び出しは、このキューから接続をポップします。

于 2009-07-23T13:09:57.443 に答える