此应用程序是递归多线程分离的。每个线程都重新生成 新的线程在它死之前。 选项1(工作)然而它是共享资源因此减慢了应用程序。 选项2应该消除这个瓶颈。
选项1有效:
std::condition_variable cv;
bool ready = false;
std::mutex mu;
// go triggers the thread's function
void go() {
std::unique_lock<std::mutex> lck( mu );
ready = true;
cv.notify_all();
}
void ThreadFunc ( ...) {
std::unique_lock<std::mutex> lck ( mu );
cv.wait(lck, []{return ready;});
do something useful
}
选项2不会触发线程:
std::array<std::mutex, DUToutputs*MaxGnodes> arrMutex ;
void go ( long m , long Channel )
{
std::unique_lock<std::mutex> lck( arrMutex[m+MaxGnodes*Channel] );
ready = true;
cv.notify_all();
}
void ThreadFunc ( ...) {
std::unique_lock<std::mutex> lck ( arrMutex[Inst+MaxGnodes*Channel] );
while (!ready) cv.wait(lck);
do something useful
}
如何让选项#2工作?
答案 0 :(得分:2)
选项2 中的代码在变量ready
上包含所谓的数据竞争,因为此变量的读写操作不再同步。具有数据竞争的程序的行为未定义。您可以将bool ready
更改为std::atomic<bool> ready
来删除数据竞赛。
这应该已经解决了选项2 中的问题。但是,如果您使用 std::atomic
,还可以进行其他优化:
std::atomic<bool> ready{false};
void go(long m, long Channel) {
// no lock required
ready = true;
cv.notify_all();
}
void ThreadFunc( ...) {
std::unique_lock<std::mutex> lck(arrMutex[Inst+MaxGnodes*Channel]);
cv.wait(lck, [] { return ready; });
// do something useful
}