我有 NUM_THREADS 个线程,线程中有以下代码:
/*
Calculate some_value;
*/
//Critical section to accummulate all thresholds
{
boost::mutex::scoped_lock lock(write_mutex);
T += some_value;
num_threads++;
if (num_threads == NUM_THREADS){
T = T/NUM_THREADS;
READY = true;
cond.notify_all();
num_threads = 0;
}
}
//Wait for average threshold to be ready
if (!READY)
{
boost::unique_lock<boost::mutex> lock(wait_mutex);
while (!READY){
cond.wait(lock);
}
}
//End critical section
/*
do_something;
*/
基本上,我希望所有线程在继续之前等待 READY 信号。 num_thread 设置为 0,并且在创建线程之前 READY 为 false。偶尔会发生死锁。有人可以帮忙吗? 所有的boost变量都全局声明如下:
boost::mutex write_mutex;
boost::mutex wait_mutex;
boost::condition cond;
最佳答案
代码在 READY
标志上有一个竞争条件(我假设它只是一个 bool
变量)。可能发生的情况(即线程执行交错的一种可能变体)是:
Thread T1: Thread T2:
if (!READY)
{
unique_lock<mutex> lock(wait_mutex); mutex::scoped_lock lock(write_mutex);
while (!READY) /* ... */
{ READY = true;
/* !!! */ cond.notify_all();
cond.wait(lock);
}
}
测试 READY
标志的代码与设置它的代码不同步(注意这些关键部分的锁是不同的)。当 T1 处于标志测试和等待 cond
之间的“空洞”时,T2 可能会设置标志并向 cond
发送信号,而 T1 可能会错过。
最简单的解决方案是为 READY
的更新和条件通知锁定正确的互斥量:
/*...*/
T = T/NUM_THREADS;
{
boost::mutex::scoped_lock lock(wait_mutex);
READY = true;
cond.notify_all();
}
关于c++ - 升压同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9014374/