プロジェクトからすべてのブースト参照を取り除き、純粋な C++ 11 に切り替えようとしています。
ある時点で、バリアが「go」コマンドを発行するのを待って作業を行い (N 個のスレッドに分散)、すべての作業が終了したときに同期するスレッド ワーカーが作成されます。基本的な考え方は、メインループが go order (boost::barrier .wait()) を与え、同じ関数で結果を待つというものです。
別のプロジェクトで、Boost バージョンに基づいてカスタム メイドの Barrier を実装しましたが、すべてが完全に機能しました。実装は次のとおりです。
Barrier.h:
class Barrier {
public:
Barrier(unsigned int n);
void Wait(void);
private:
std::mutex counterMutex;
std::mutex waitMutex;
unsigned int expectedN;
unsigned int currentN;
};
バリア.cpp
Barrier::Barrier(unsigned int n) {
expectedN = n;
currentN = expectedN;
}
void Barrier::Wait(void) {
counterMutex.lock();
// If we're the first thread, we want an extra lock at our disposal
if (currentN == expectedN) {
waitMutex.lock();
}
// Decrease thread counter
--currentN;
if (currentN == 0) {
currentN = expectedN;
waitMutex.unlock();
currentN = expectedN;
counterMutex.unlock();
} else {
counterMutex.unlock();
waitMutex.lock();
waitMutex.unlock();
}
}
このコードは iOS と Android の NDK で問題なく使用されていますが、Visual Studio 2013 プロジェクトで試してみると、ミューテックスをロックしたスレッドのみがロックを解除できるようです (アサーション: 所有されていないミューテックスのロック解除)。
C ++ 11で機能する、回転しない(このようなブロッキング)バージョンのバリアを使用できますか? ビジー待機を使用するバリアを見つけることができましたが、これは防止したいものです (本当に理由がない場合を除きます)。