5

ワーカー(スレッドとして表される)と(複数の)キューのシステムを構築する必要があります。個々のジョブはキューの1つで待機しており、ワーカースレッドがそれらを処理するのを待機しています。各ワーカーは、一部のキューからのみジョブを処理できます。スピン待機はありません。C / C ++、pthread、標準POSIX。

私にとっての問題は、「複数のキュー」のことです。私はこれを単一のキューで実装する方法を知っています。ワーカーは、処理できるすべてのキューを待機する必要があります(いずれかのキューを待機します)。

WindowsではWaitForMultipleObjectsを使用しますが、これはマルチプラットフォームである必要があります。

このための特定のコードは必要ありません。使用するモデルのヒントまたは説明だけが必要です。前もって感謝します。

4

8 に答える 8

5

どうですか:

  • すべてのワーカー スレッドがセマフォで待機する
  • キューに何かが追加されると、セマフォがインクリメントされ、単一のスレッドが起動されます
  • スレッドは、関心のあるキューをチェックし、そのうちの 1 つを処理して、セマフォの待機に戻ります。

キューへの実際の読み取りと書き込みを制御するには、追加のミューテックスが必要になります。

于 2009-05-22T17:19:03.210 に答える
4

できることは、条件変数を使用することです。ワーカー スレッドを条件変数で待機させます。ジョブがいずれかのジョブ キューに追加されたら、条件変数にシグナルを送ります。次に、ワーカー スレッドが起動すると、待機しているキューをチェックします。それらのいずれかにジョブがある場合、そのジョブをキューから外します。それ以外の場合は、条件変数の待機に戻ります。条件変数を待機すると、スレッドがスリープ状態になるため、CPU 時間が消費されません。

もちろん、ジョブキューへのすべてのアクセスをミューテックス (例: pthread_mutex_t) で保護する必要があることは言うまでもありません。

于 2009-05-22T17:03:50.810 に答える
1

各キューのワーカー数が多すぎない場合は、ワーカーごとに条件変数を作成できます。

于 2009-05-22T17:03:05.180 に答える
0

boost::threadboost::condition、およびstd::queueを使用する必要があるようです。

于 2009-05-22T17:03:20.950 に答える
0

各キューに個別のロックを設定する代わりに、すべてのキューに 1 つのロックを設定してみませんか?

  1. ロックで待機
  2. ロックを取得します。
  3. どのキューからでもデキュー
  4. ロックを解除する
  5. デキューされたアイテムを処理する
  6. ステップ 1 に進む

デキューにかかる時間はごくわずかであると仮定すると (したがって、ロックが保持される時間はごくわずかです)、複数のロックは必要ないかもしれません。

于 2009-05-22T17:04:59.577 に答える
0

次のようなことができます: 各ジョブには、それに関連付けられた「キュー」があります。例えば:

2 つのキューがあるとします。あなたの仕事は次のように言えます:

job[0].queue = 1; /* That job is in queue 1 */
job[1].queue = 1;
job[2].queue = 2; /* this job is in queue 2 */
... 
etc

それで、あなたはあなたの「糸の袋」を手に入れました。スレッドは単純にジョブ (job[2] など) を選択します。そのスレッドがキュー 1 からのジョブの処理のみを許可されている場合、スレッドはそのジョブを準備完了キューに戻し、別のジョブを選択します。

したがって、各スレッドは、処理が許可されているキューを認識しており、ジョブを選択するときに、ジョブの「キュー」フィールドが一致することを確認します。そうでない場合は、別のジョブを選択します。

(これは多くの点で、複数のコアの Linux でプロセスのスケジューリングがどのように機能するかです。各プロセスには、実行が許可されているプロセッサを示すビットマスクがあり、プロセッサは実行する前にそのプロセスの実行が「許可」されていることを確認します。 )

于 2009-05-22T17:08:14.283 に答える
0

私がすることは、boost::asio を使用してデータをキューに入れ、複数のスレッドがそれを実行できるようにすることです。post コマンドを介して ref をキューに渡し、それに応じてスレッドを処理させることができます。

于 2009-05-22T17:04:19.997 に答える
0

私は最近これについて考えていましたが、思いつく唯一のアイデアは (スレッドセーフなキューがあると仮定して) 単一のキューにサービスを提供する複数のスレッドのみを持つことです。

次に、1 つまたは複数の作業生成スレッドが単一のキューにジョブを追加し、1 つまたは複数のワーカー スレッドが処理対象を見つけるまでキューでブロックするように設定できます。

複数のワーカー スレッドがポーリングしなければならない複数のキューがある場合、解決策として、キューごとに 1 つのスレッドを追加し、キューを 1 つ追加することが考えられます。余分なスレッドはそれぞれ独自の単一のキューでブロックされますが、単にジョブを余分なキューに転送します。これで、既存のワーカー スレッドは単一のキューでのブロックに戻りました。

于 2011-06-25T21:40:14.053 に答える