繁体   English   中英

std :: condition_variable线程安全吗?

[英]Is std::condition_variable thread-safe?

我有一些像这样的代码:

std::queue<myData*> _qDatas;
std::mutex _qDatasMtx;

发电机功能

void generator_thread()
{
  std::this_thread::sleep_for(std::chrono::milliseconds(1));
  {
    std::lock_guard<std::mutex> lck(_qDatasMtx);
    _qData.push(new myData);
  }
  //std::lock_guard<std::mutex> lck(cvMtx); //need lock here?
  cv.notify_one();
}

消费者功能

void consumer_thread()
{
  for(;;)
  {
    std::unique_lock lck(_qDatasMtx);
    if(_qDatas.size() > 0)
    {
       delete _qDatas.front();
       _qDatas.pop();
    }
    else
      cv.wait(lck);
  }
}

因此,如果我有几十个生成器线程和一个消费者线程,在每个线程中调用cv.notify_one()时是否需要互斥锁?

并且std :: condition_variable线程安全吗?

可以从没有锁的多个线程调用notify_one

但是,为了使正常操作工作并且没有通知“滑过”的机会,您必须保持锁定条件变量在您修改虚假唤醒防护的点和/或封装条件变量检查读取之间保护,以及你通知一个的点。

您的代码似乎通过了该测试。 但是这个版本更清楚:

std::unique_lock lck(_qDatasMtx);
for(;;) {
  cv.wait(lck,[&]{ return _qDatas.size()>0; });
  delete _qDatas.front();
  _qDatas.pop();
}

它减少了虚假的解锁/重新锁定。

在每个线程中调用cv.notify_one()时是否需要mutex锁?

没有

std::condition_variable线程安全吗?


在调用wait ,您将传递一个锁定的mutex ,该mutex立即被解锁以供使用。 在调用notify你不要使用相同的mutex锁将其锁定,因为会发生什么(详见链接):

  1. 通知
  2. 正在等待的唤醒线程
  3. 锁定互斥锁以供使用

来自std::condition_variable

在std :: condition_variable上执行notify_one或notify_all(不需要保持锁定以进行通知)

std::condition_variable::notify_all

通知线程不需要将锁定保持在与等待线程所持有的互斥锁相同的互斥锁上;


关于您的代码段:

//std::lock_guard<std::mutex> lck(cvMtx); //need lock here?
cv.notify_one();

不,你不需要锁。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM