gpt4 book ai didi

c++ - 为什么我需要 std::condition_variable?

转载 作者:IT老高 更新时间:2023-10-28 14:00:26 26 4
gpt4 key购买 nike

我发现由于虚假唤醒,std::condition_variable 很难使用。所以有时我需要设置一个标志,例如:

atomic<bool> is_ready;

我在调用 notify(notify_one()notify_all())之前将 is_ready 设置为 true,然后我等待:

some_condition_variable.wait(some_unique_lock, [&is_ready]{
return bool(is_ready);
});

我有什么理由不应该这样做:(编辑:好吧,这真是个坏主意。)

while(!is_ready) {
this_thread::wait_for(some_duration); //Edit: changed from this_thread::yield();
}

如果condition_variable选择了等待时间(不知道是不是真的),我更喜欢自己选择。

最佳答案

你可以用任何一种方式编写代码:

  1. 使用原子和轮询循环。
  2. 使用 condition_variable

我在下面为您编写了两种方式。在我的系统上,我可以实时监控任何给定进程正在使用多少 CPU。

首先是轮询循环:

#include <atomic>
#include <chrono>
#include <iostream>
#include <thread>

std::atomic<bool> is_ready(false);

void
test()
{
std::this_thread::sleep_for(std::chrono::seconds(30));
is_ready.store(true);
}

int
main()
{
std::thread t(test);
while (!is_ready.load())
std::this_thread::yield();
t.join();
}

对我来说,这需要 30 秒来执行,而在执行过程中大约需要 99.6% 的 cpu。

或者使用 condition_variable:

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

bool is_ready(false);
std::mutex m;
std::condition_variable cv;

void
test()
{
std::this_thread::sleep_for(std::chrono::seconds(30));
std::unique_lock<std::mutex> lk(m);
is_ready = true;
cv.notify_one();
}

int
main()
{
std::thread t(test);
std::unique_lock<std::mutex> lk(m);
while (!is_ready)
{
cv.wait(lk);
if (!is_ready)
std::cout << "Spurious wake up!\n";
}
t.join();
}

这具有完全相同的行为,除了在 30 秒执行期间,进程占用 0.0% cpu。如果您正在编写一个可以在电池供电的设备上运行的应用程序,那么电池供电的设备几乎无限容易。

诚然,如果您对 std::condition_variable 的实现非常糟糕,它可能会像轮询循环一样效率低下。但是在实践中,这样的供应商应该很快就会倒闭。

更新

为了咧嘴笑,我用一个虚假的唤醒检测器增加了我的 condition_variable 等待循环。我再次运行它,它没有打印出任何东西。没有一个虚假的唤醒。这当然不能保证。但它确实证明了高质量的实现可以实现什么。

关于c++ - 为什么我需要 std::condition_variable?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16350473/

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