c++ - condition_variable::notify_one 不会立即解除等待?

标签 c++ mutex condition-variable

我有一个关于notify_one函数的问题。在下面的代码中,

#include <iostream>
#include <condition_variable>
#include <thread>
#include <chrono>
#include <mutex>

std::condition_variable cv;
std::mutex m;
bool ready = false;

void f()
{
  std::unique_lock<std::mutex> lk(m);
  std::cout << "get into wait, ready=" << ready << std::endl;
  cv.wait(lk, []() { return ready; });
  std::cout << "get out of wait, ready=" << ready << std::endl;
}

int main()
{
  std::thread a(f);

  std::this_thread::sleep_for(std::chrono::seconds(1));

  {
    std::unique_lock<std::mutex> lk(m, std::defer_lock);
    if (lk.try_lock()) {
      std::cout << "main try_lock success, ready=" << ready << std::endl;
      ready = true;
    }
  }
  std::cout << "main notify, ready=" << ready << std::endl;
  cv.notify_one();

  // std::cout << "hello" << std::endl;

  {
    std::unique_lock<std::mutex> lk(m, std::defer_lock);
    if (lk.try_lock()) {
      std::cout << "main try_lock success, ready=" << ready << std::endl;
      ready = true;
    }
  }
  std::cout << "main notify, ready=" << ready << std::endl;
  cv.notify_one();

  a.join();

  return 0;
}

我得到以下结果,

get into wait, ready=0
main try_lock success, ready=0
main notify, ready=1
main try_lock success, ready=1
main notify, ready=1
get out of wait, ready=1

但我预计结果如下,因为根据 page ,如果调用notify_one,则wait被解除阻塞,并重新获取mutex(m)的锁。

get into wait, ready=0
main try_lock success, ready=0
main notify, ready=1
main notify, ready=1
get out of wait, ready=1

我发现如果我注释掉std::cout << "hello" << std::endl;我得到了预期的结果。在我看来,notify_one 不会立即解除等待。这是正确的吗?

非常感谢!

最佳答案

Looks to me like notify_one does not immediately unblock the wait. It is correct?

通知立即解除阻塞等待,这意味着等待能够在通知后恢复。也就是说,休眠线程被标记为可运行。

但是,调度程序不一定立即重新启动它。如果它必须抢占一些已经运行的线程/进程,它可能会等到yield、系统调用或其他取消点,否则甚至不会查看新运行的线程,直到当前时间片结束。

解除阻塞与强制立即上下文切换不同(这是幸运的,否则同步的成本会更高)。

关于c++ - condition_variable::notify_one 不会立即解除等待?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64891918/

相关文章:

go - sync.Mutex 和 *sync.Mutex 哪个更好?

c++ - 为什么在使用绝对时间调用时 boost::timed_wait 会永远阻塞?

c - 使用 pthread_cond_wait 和 pthread_cond_signal 保证 yield

C++ : Double free or corruption (out)

c++ - 如何在 C++ 中编写默认构造函数?

c - Mutex - 使用线程计算文件中 char 的出现次数

c++ - 互斥体更改是否会广播到多核系统上的其他内核?

c++ - std::condition_variable在阻塞之前是否真的解锁了给定的unique_lock对象?

c++ - 在 C++/Eigen 中求解线性方程

c++ - 在具有 {} 任何其他具有良好运行时间的方法之间提取数据