使用std :: mutex数组时不会触发conditional_variable

时间:2014-07-13 19:35:41

标签: c++ multithreading c++11

此应用程序是递归多线程分离的。每个线程都重新生成 新的线程在它死之前。 选项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工作?

1 个答案:

答案 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
}