4

最適な同期方法を見つけようとしているシナリオがあります。C++11 の std::thread が存在することを前提としているため、さまざまなスレッド ライブラリの違いなどについて心配する必要はありません。

シナリオはこうです。メイン スレッドであるスレッド a は、一連のワーカー スレッドにタスクを渡したいと考えています。そして、ひとまず最後の命令を出した後、すべてのスレッドが作業を完了するのを待つ必要があります。私たちは彼らに加わりたくありません。ただ彼らが与えられた仕事を終えるのを待ちます。次に、スレッド a は、すべてのスレッドから収集されたデータを分析し、コマンドをワーカーに送信して手順を再開する必要があります。

要するに、これらは手順です。

  1. スレッド a はコマンド x をすべてのワーカー スレッドに送信します。
  2. スレッド a は、すべてのワーカーが終了するまで待機します。
  3. スレッド a が処理を行います。
  4. 1に戻ります。

何を使用することをお勧めしますか? 単純なミューテックス?条件変数? 2つの組み合わせ?可能な限り効率的に同期を構成する方法に関するヒントをいただければ幸いです。

4

1 に答える 1

2

n 個のワーカー スレッドと 1 個のメイン スレッドaがあり、ワーカーにタスクを委任し、それらのタスクが完了するのを待ってから新しいタスクのバッチを割り当てる必要があります。

基本的な手法は、バリア ( などboost::barrier) を使用して、ワーカー スレッドと の終了を同期することaです。

バリアは で初期化されn+1ます。メイン スレッドaはバリア上で待機し、各ワーカー スレッドはタスクの最後に同じことを行います。最後のスレッドwaitがバリアで呼び出されると、すべてのスレッドが起動され、メイン スレッドは作業を続行できます。新しいタスクが割り当てられるまでワーカー スレッドをブロックするために、2 番目のバリアを追加することをお勧めします。

ワーカー スレッドの本体は、次の疑似コードのようになります。

while (running) {
     startbarrier.wait(); // wait for main thread to signal start
     do_work();
     endbarrier.wait(); // signal end of work
 }

同じことがセマフォでも実装できます。セマフォとバリアはどちらもミューテックスと条件変数で実装できます。

詳細については、この SO の質問を参照してください。

于 2013-03-17T22:52:15.577 に答える