gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 06:57:32 27 4
gpt4 key购买 nike

我有一个关于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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com