我有两个线程和一个由第二个线程设置的标志。我可以使用 atomic_bool
,但我希望能够等待* 在第一个线程上设置标志。我该怎么做?
我猜我不能使用condition_variable
,因为如果第二个线程在第一个线程开始等待之前调用notify_one
,线程将不会唤醒。
此外,检查标志是否已经设置应该相当快。我想这应该很简单,但我只是卡住了,所以我在这里问。提前致谢。
*编辑:当然是阻塞,而不是忙等待。抱歉,如果不清楚。
最佳答案
在 cbreak 和 Ravadre(注释)的帮助下,我从这里得到:
int main()
{
std::mutex m;
std::condition_variable cv;
std::thread t([&] {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::unique_lock<std::mutex> lock(m);
cv.wait(lock);
std::cout << "Yay!\n";
});
cv.notify_one();
t.join();
}
通常根本不会终止,到这里:
int main()
{
std::mutex m;
std::condition_variable cv;
bool flag = false;
std::thread t([&] {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::unique_lock<std::mutex> lock(m);
cv.wait(lock, [&] { return flag; });
std::cout << "Yay!\n";
});
{
std::lock_guard<std::mutex> lock(m);
flag = true;
}
cv.notify_one();
t.join();
}
这实际上完成了工作,但似乎仍然有很多不必要的开销。随意发布等效但性能更高(或更优雅)的答案,我会很乐意接受。请只使用标准 C++11,如果不是,请解释为什么标准 C++11 不能这样做。
编辑:我还写了一个类 safe_flag 来封装它(再次感谢 cbreak);随时提出任何改进建议。
class safe_flag
{
mutable std::mutex m_;
mutable std::condition_variable cv_;
bool flag_;
public:
safe_flag()
: flag_(false)
{}
bool is_set() const
{
std::lock_guard<std::mutex> lock(m_);
return flag_;
}
void set()
{
{
std::lock_guard<std::mutex> lock(m_);
flag_ = true;
}
cv_.notify_all();
}
void reset()
{
{
std::lock_guard<std::mutex> lock(m_);
flag_ = false;
}
cv_.notify_all();
}
void wait() const
{
std::unique_lock<std::mutex> lock(m_);
cv_.wait(lock, [this] { return flag_; });
}
template <typename Rep, typename Period>
bool wait_for(const std::chrono::duration<Rep, Period>& rel_time) const
{
std::unique_lock<std::mutex> lock(m_);
return cv_.wait_for(lock, rel_time, [this] { return flag_; });
}
template <typename Rep, typename Period>
bool wait_until(const std::chrono::duration<Rep, Period>& rel_time) const
{
std::unique_lock<std::mutex> lock(m_);
return cv_.wait_until(lock, rel_time, [this] { return flag_; });
}
};
关于c++ - 等待 atomic_bool,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14920725/