でコードをコンパイルし、スレッドのバリアコンセプト自体はC++ 11またはVisual C++の一部ではありません。
純粋なC++ 11では、condition variableとカウンタを使用できます。
class my_barrier
{
public:
my_barrier(int count)
: thread_count(count)
, counter(0)
, waiting(0)
{}
void wait()
{
//fence mechanism
std::unique_lock<std::mutex> lk(m);
++counter;
++waiting;
cv.wait(lk, []{return counter >= thread_count;});
--waiting;
if(waiting == 0)
{
//reset barrier
counter = 0;
}
lk.unlock();
}
private:
std::mutex m;
std::condition_variable cv;
int counter;
int waiting;
int thread_count;
};
my_barrier barrier;
void func()
{
operation1();
barrier.wait();
operation2();
}
述語が満たされるまで各スレッドが待機します。最後のスレッドは述語を有効にし、待機中のスレッドを続行させます。 バリアを再利用する場合(たとえば、関数を複数回呼び出すなど)、別の 変数が必要で、カウンタをリセットする必要があります。
この現在の実装には制限があります。 func();func();
を2回呼び出しても、スレッドは2回目の待機を行わないことがあります。
簡単な方法は、2つの異なる機能に作業を分けることです。メインスレッドでは、最初の半分を実行するスレッドを作成し、それらのすべてを結合し、後半を実行します。 – Zereges
これは実際に複雑になるでしょう。私の建築は私に仕事を分けることを許しません。 – GregPhil
これにはbarrierという実際のスレッドプリミティブがあります。私はpthreadがこれを実装していることを知っています。また、boostはこれを実装します。 –