簡體   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