我一直在尝试摆脱所有提升引用的项目,并切换到纯C++ 11。
一方面,创建了线程工作程序,这些线程工作程序等待发出“go”命令的障碍,进行工作(遍及N个线程),并在所有工作完成时进行同步。基本思想是主循环给出执行顺序(boost::barrier .wait()),并使用相同的函数等待结果。
我在另一个项目中实现了一个基于Boost版本的定制屏障,并且一切正常。实现如下:
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;
};
Barrier.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的任何非旋转(阻塞,例如这一步)障碍吗?我只能找到使用忙碌等待的障碍,这是我要防止的事情(除非确实没有理由)。
最佳答案
class Barrier {
public:
explicit Barrier(std::size_t iCount) :
mThreshold(iCount),
mCount(iCount),
mGeneration(0) {
}
void Wait() {
std::unique_lock<std::mutex> lLock{mMutex};
auto lGen = mGeneration;
if (!--mCount) {
mGeneration++;
mCount = mThreshold;
mCond.notify_all();
} else {
mCond.wait(lLock, [this, lGen] { return lGen != mGeneration; });
}
}
private:
std::mutex mMutex;
std::condition_variable mCond;
std::size_t mThreshold;
std::size_t mCount;
std::size_t mGeneration;
};
关于multithreading - 在C++ 11中实现boost::barrier,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24465533/