簡體   English   中英

即使調用了notify_all,工作線程也一直在condition_variable處等待

[英]worker thread keeps waiting at condition_variable even the notify_all is called

我得到如下代碼:

std::mutex mutex;
std::condition_variable condition_variable;
bool finish = false;

void test() {
  while (true) {
    std::unique_lock<std::mutex> lock(mutex);
    condition_variable.wait(lock);
    if (finish){
      std::cout << "finish detected" << std::endl;
      return;
    }
  }
}

int main() {
  std::thread t(test);
  std::unique_lock<std::mutex> lock(mutex);
  finish = true;
  lock.unlock();
  //sleep(1);
  condition_variable.notify_all();
  std::cout << "notify_all" << std::endl;
  t.join();
}

並且代碼在運行時不會終止, notify_all日志將打印,但finish detected日志不會。 如果我使用調試模式,代碼將成功終止,因此我無法提供有關運行代碼狀態的明確線索,但如果我釋放sleep(1) ,代碼將起作用。

那么任何人都可以幫助我的代碼有什么問題嗎?

條件變量沒有狀態,因此當您發出信號並且沒有服務員時,信號會丟失。 condition_variable.notify_all()condition_variable.wait(lock);之前執行時,它會發生在您的代碼中condition_variable.wait(lock); .

代碼沒有使用正確的方法來等待條件變量。 正確的方法是:

  1. 鎖定互斥鎖。
  2. 檢查條件( finishfinish )。
  3. 如果條件不滿足,則等待條件變量。 條件變量可以被虛假喚醒 轉到 2。

使固定:

void test() {
    std::unique_lock<std::mutex> lock(mutex);
    while(!finish)
        condition_variable.wait(lock);
    std::cout << "finish detected" << std::endl;
}

condition_variable::wait另一個重載可以為您執行while循環:

void test() {
    std::unique_lock<std::mutex> lock(mutex);
    condition_variable.wait(lock, [&finish]{ return finish; });
    std::cout << "finish detected" << std::endl;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM