【发布时间】:2015-11-20 10:37:00
【问题描述】:
前言:我在这里看到过类似的问题,但似乎没有一个回答我的问题。
是否有可靠的方法来确保消费者线程中的 wait() 方法在生产者线程第一次调用 notify_one() 之前被调用?
即使在消费者线程中有unique_lock,也有可能生产者线程会先运行,锁定互斥体并在消费者调用wait()之前调用notify(),因此,我的应用程序将首先丢失@ 987654327@电话。
编辑:感谢您的所有回答,他们确实帮助了我。我的问题是这个消费者循环中的第一个 wait-notify() :
while (!timeToQuit) {
gdcv.wait(gdcondlock);
gdlock.lock();
//spurious wakeup
if (gdQueue.empty()) {
gdlock.unlock();
continue;
}
//some work here
gdlock.unlock();
}
我想我必须为第一次循环迭代编写额外的代码。
EDIT2:这个循环和第二个锁(unique_lock btw)之所以存在,是因为有多个生产者和消费者访问队列。
EDIT3:在boost::lockfree::queue 的帮助下等待这个特定线程的正确方法,以防万一有人遇到类似问题:
nfq_data* data;
while (!timeToQuit) {
gdcv.wait(gdlock,[&]{return !gdQueue.empty() || timeToQuit;});
gdQueue.pop(data);
gdlock.unlock();
}
【问题讨论】:
-
听起来几乎就像您需要的是信号量而不是条件变量 - 例如,请参见此处:stackoverflow.com/questions/4792449/…
-
你为什么打电话给
gdlock.lock()和gdlock.unlock()而不是lock_guard?你不喜欢简单和正确吗? -
为什么你还有两把锁?听起来您甚至不需要问代码是否更惯用的问题
-
不能用
lock_guard lg(m); gdcv.wait(lg, [&]{ return gdQueue.empty(); })替换整个东西吗?这应该做正确的事情,即如果条件为真则立即返回,或者等到通知并且条件为真。 -
您可能有一个非常特殊的情况,但在正常情况下,不需要无锁容器。当容器被修改、通知和等待时,应该使用相同的互斥锁。
标签: c++ multithreading c++11 condition-variable