【发布时间】:2016-11-15 17:49:32
【问题描述】:
假设有许多线程由一个循环运行相同函数的实例组成,但每次迭代的开始都需要同步(因此首先完成的线程必须等待最后一个开始新的迭代)。在 c++11 中如何做到这一点?
...
帖子的其余部分只是我尝试过的以及失败的原因。
我正在使用计数器“sync”,最初设置为 3(线程数)。每个线程在函数结束时都会从这个计数器中减去 1 并开始等待。当计数器为 0 时,表示它们 3 已经完成了一轮,所以主线程会将计数器重置为 3,并通知线程唤醒它们。
这在大多数情况下都有效,但有时一两个线程无法唤醒。
所以这些是全局变量:
mutex syncMutex;
condition_variable syncCV;
int sync;
这是在线程中循环运行的函数的末尾:
unique_lock<mutex> lk(syncMutex);
cout << "Thread num: " << mFieldNum << " got sync value: " << sync;
sync --;
syncCV.notify_all();
cout << " and goes to sleep..." << endl;
syncCV.wait(lk, []{return sync == numFields;});
cout << "Thread num: " << mFieldNum << " woke up" << endl;
}
这在主线程中循环运行:
unique_lock<mutex> lk(syncMutex);
syncCV.wait(lk, []{return sync == 0;});
sync = 3;
lk.unlock();
cout << "Notifying all threads!" << endl;
syncCV.notify_all();
这是它失败时产生的输出(线程#3 没有唤醒):
Thread num: 1 got sync value: 3 and goes to sleep...
Thread num: 2 got sync value: 2 and goes to sleep...
Thread num: 3 got sync value: 1 and goes to sleep...
Notifying all threads!
Thread num: 1 woke up
Thread num: 2 woke up
Thread num: 3 woke up
Thread num: 2 got sync value: 3 and goes to sleep...
Thread num: 1 got sync value: 2 and goes to sleep...
Thread num: 3 got sync value: 1 and goes to sleep...
Notifying all threads!
Thread num: 2 woke up
Thread num: 1 woke up
Thread num: 2 got sync value: 3 and goes to sleep...
Thread num: 1 got sync value: 2 and goes to sleep...
有人知道吗?感谢您的阅读。
【问题讨论】:
-
由于每个线程都在一个循环中运行,所以在线程 1 或 2 唤醒后,sync-- 被执行,在线程 3 []{return sync == numFields;} 谓词执行之前。谓词被评估为假,因此线程 3 没有唤醒。
-
谢谢@TonyJ 你知道如何解决这个问题吗?
标签: c++ multithreading synchronization mutex condition-variable