了解使用std :: condition_variable的示例 [英] Understanding the example of using std::condition_variable
问题描述
有一个使用 condition_variable
的例子,取自 cppreference.com :
There is example of using condition_variable
taken from cppreference.com:
#include <condition_variable>
#include <mutex>
#include <thread>
#include <iostream>
#include <queue>
#include <chrono>
int main()
{
std::queue<int> produced_nums;
std::mutex m;
std::condition_variable cond_var;
bool done = false;
bool notified = false;
std::thread producer([&]() {
for (int i = 0; i < 5; ++i) {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::lock_guard<std::mutex> lock(m);
std::cout << "producing " << i << '\n';
produced_nums.push(i);
notified = true;
cond_var.notify_one();
}
std::lock_guard<std::mutex> lock(m);
notified = true;
done = true;
cond_var.notify_one();
});
std::thread consumer([&]() {
while (!done) {
std::unique_lock<std::mutex> lock(m);
while (!notified) { // loop to avoid spurious wakeups
cond_var.wait(lock);
}
while (!produced_nums.empty()) {
std::cout << "consuming " << produced_nums.front() << '\n';
produced_nums.pop();
}
notified = false;
}
});
producer.join();
consumer.join();
}
如果变量 done
在消费者线程启动之前, true
,消费者线程将不会收到任何消息。事实上, sleep_for(seconds(1))
几乎避免了这种情况,但可能在理论上(或如果没有 sleep
in code)?
If variable done
comes true
before the consumer thread is started, the consumer thread will not get any message. Indeed, sleep_for(seconds(1))
almost avoids such situation, but could it be possible in theory (or if don't have sleep
in code)?
在我看来,正确的版本应该像这样强制运行消费者循环至少一次: / p>
In my opinion correct version should look like this to force running consumer loop at least once:
std::thread consumer([&]() {
std::unique_lock<std::mutex> lock(m);
do {
while (!notified || !done) { // loop to avoid spurious wakeups
cond_var.wait(lock);
}
while (!produced_nums.empty()) {
std::cout << "consuming " << produced_nums.front() << '\n';
produced_nums.pop();
}
notified = false;
} while (!done);
});
推荐答案
是的,你是绝对正确的:远程)可能性,消费者线程将不会开始运行,直到 done
已设置。此外,在生产者线程中对 done
的写入和在消费者线程中的读取产生竞争条件,并且行为是未定义的。在您的版本中有相同的问题。在每个函数中将互斥量包裹在整个循环中。对不起,没有能力写正确的代码。
Yes, you are absolutely right: there is a (remote) possibility that the consumer thread will not start running until after done
has been set. Further, the write to done
in the producer thread and the read in the consumer thread produce a race condition, and the behavior is undefined. Same problem in your version. Wrap the mutex around the entire loop in each function. Sorry, don't have the energy to write the correct code.
这篇关于了解使用std :: condition_variable的示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!