std :: condition_variable wait()和notify_one()同步

Vla*_*aev 4 c++ multithreading c++11

前言:我在这里看到过类似的问题,但其中没有一个似乎回答了我的问题.

是否有一种可靠的方法可以确保在第一次从生产者线程调用notify_one()之前调用消费者线程中的wait()方法?

即使在消费者线程中使用unique_lock,生产者线程也有可能首先运行,锁定互斥锁并在消费者调用wait()之前调用notify(),因此,我的应用程序将首先缺少notify()调用

编辑:谢谢你的所有答案,他们确实帮助了我.我的问题是这个消费者循环中的第一个wait-notify():

while (!timeToQuit) {
    gdcv.wait(gdcondlock);
    gdlock.lock();
    //spurious wakeup
    if (gdQueue.empty()) {
      gdlock.unlock();
      continue;
    }
    //some work here
    gdlock.unlock();
} 
Run Code Online (Sandbox Code Playgroud)

我想,我将不得不为第一次循环迭代编写额外的代码.

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();
  }
Run Code Online (Sandbox Code Playgroud)

Dav*_*rtz 5

即使在消费者线程中使用unique_lock,生产者线程也有可能首先运行,锁定互斥锁并在消费者调用wait()之前调用noify(),因此,我的应用程序将缺少第一个nofity()调用.

消费者要么等待,要么不等.如果它有等待的东西,没有问题.如果它没有等待的东西,请不要叫"等待".它真的很简单.

wait当且仅当您想要等待时,请致电.

存在条件变量来解决如何释放锁并等待的问题,而不会冒你将等待已经发生的事情的风险.他们通过提供原子释放锁并等待的功能来解决它​​.他们不能错过一次唤醒,因为他们决定睡觉时会抓住锁.