gpt4 book ai didi

c++ - 为什么 C++20 std::condition_variable 不支持 std::stop_token?

转载 作者:行者123 更新时间:2023-12-03 12:44:10 25 4
gpt4 key购买 nike

在 C++20 标准库中 std::condition_variable_any::wait() 家庭支持 std::stop_token用于通用线程取消,但 std::condition_variable才不是。
P0660R10 Stop Token and Joining Thread, Rev 10说:

New in R6

  • User condition_variable_any instead of consition_variable to avoid all possible races, deadlocks, and unintended undefined behavior.

我认为以下代码可以安全地模拟 condition_variable::wait()stop_token消除。我错过了什么?是否有微妙的边缘情况?
template<class Lock, class Predicate>
bool cv_wait_with_stoken(
std::condition_variable& cv, Lock& lock, std::stop_token stoken, Predicate pred)
{
std::stop_callback callback{ stoken, [&cv]{ cv.notify_all(); } };
while (!stoken.stop_requested()) {
if (pred())
return true;
cv.wait(lock);
}
return pred();
}

最佳答案

是的,存在竞争条件。
通常,对于条件变量,您必须将互斥锁保留一段时间 之间 修改保护状态(通常是一个变量)并通知条件变量。如果不这样做,您可能会错过信号。
使您的状态成为原子变量并不能避免这个问题。
cv 的等待代码首先检查状态。如果失败,它会自动地删除锁并等待信号。
如果您的停止 token 在检查后设置在该间隙中,但在等待之前,则停止 token 调用通知全部,条件变量不会选择通知全部。cv.notify_all()必须先获得该锁。这会打开一整 jar 蠕虫。
不要使用这段代码,它可能会由于双重锁定或其他无数事情而严重崩溃,但理论上它看起来像:

bool cv_wait_with_stoken(
std::condition_variable& cv,
Lock& lock,
std::stop_token stoken,
Predicate pred
) {
std::stop_callback callback{ stoken, [&cv]{
lock.lock();
lock.unlock();
cv.notify_all();
} };
while (!stoken.stop_requested()) {
if (pred())
return true;
cv.wait(lock);
}
return pred();
}
或许可以到 try_lock在那里,我将不得不做很多艰苦的证明工作。

关于c++ - 为什么 C++20 std::condition_variable 不支持 std::stop_token?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66309276/

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