【发布时间】:2020-08-05 12:34:35
【问题描述】:
从文档语言中我不清楚是否必须在等待之前检查 std::condition_variable 的谓词。
在cppreference,有这样的说法:
Any thread that intends to wait on std::condition_variable has to
1. ...
2. check the condition, in case it was already updated and notified
在实践中,似乎不需要检查。如果没有,我只是担心未定义的行为。
我关心的情况是消费者在生产者之后上线的情况(即条件变量在另一个线程开始等待之前已经被一个线程通知):
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
int main() {
std::condition_variable condition_var;
std::mutex mutex;
std::vector<std::thread> threads;
bool flag = false;
// Producer
threads.emplace_back([&]() {
{
std::lock_guard<std::mutex> lock(mutex);
flag = true;
printf("%s\n", "flag = true");
}
condition_var.notify_all();
});
// Consumer
threads.emplace_back([&]() {
std::this_thread::sleep_for(std::chrono::seconds(3));
{
std::unique_lock<std::mutex> lock(mutex);
condition_var.wait(lock, [&]() { return flag; });
printf("%s\n", "Consumer finished");
}
});
for (auto& thread : threads) {
if (thread.joinable()) {
thread.join();
}
}
return 0;
}
在上面的示例中,生产者启动并通知条件变量。消费者在那之后开始,并在检查条件变量之前休眠几秒钟。这实际上确保了消费者在生产者通知条件变量后开始等待。
尽管如此,代码在我的计算机上完成并且不会无限期挂起。事实上,由于它完成的速度有多快,我认为这不是由于虚假唤醒,但我不确定如何检查。
【问题讨论】:
-
你不需要检查你是否对谓词使用了重载。参见en.cppreference.com/w/cpp/thread/condition_variable/wait - 相当于
while (!pred()) { wait(lock); } -
@dewaffled 你在 cmets 中回答
标签: c++ multithreading c++11 c++14 mutex