c++ - 即使调用了notify_all,工作线程也会在condition_variable处保持等待

标签 c++ multithreading

我得到如下代码:

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 detector 日志。如果我使用 Debug模式,代码将成功终止,因此我无法提供有关正在运行的代码的状态的明确线索,但如果我释放 sleep(1),代码将正常工作。

那么有人可以帮助我的代码出了什么问题吗?

最佳答案

条件变量没有状态,因此当你向它发出信号并且没有服务员时,信号就会丢失。当 condition_variable.notify_all()condition_variable.wait(lock); 之前执行时,会在代码中发生这种情况。

代码未使用正确的方法来等待条件变量。正确的方法是:

  1. 锁定互斥锁。
  2. 检查状况(在此处完成)。
  3. 如果条件不满足,则等待条件变量。 The condition variable can be woken up spuriously 。转到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;
}

关于c++ - 即使调用了notify_all,工作线程也会在condition_variable处保持等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59267230/

相关文章:

c - 指针变量周围是否需要互斥锁?

c++ - 用于在 C++ 中读取和写入 SERVER 的多线程

c++ - 当 C++ const 方法同步可变状态时,非常量方法也必须这样做吗?

c++ - 并行但无锁地将数据刷新到磁盘?

字符串流istringstream的C++问题

c++ - 是否有特征或任何约定来检查范围或 `view_facade` 是否拥有事物? (例如 getlines)

c++ - 如何定义类似于Vector的Vector的Double Brackets/Double Iterator运算符?

c++ - std::uniform_int_distribution 放入函数中还是我用错了?

c++ - 如何从 C++ 向 Lua 库公开属性

java - run完成后调用线程对象方法