【发布时间】:2019-05-30 19:55:10
【问题描述】:
我试图了解在条件变量的情况下虚假唤醒与丢失唤醒之间的区别。以下是我尝试过的一小段代码。我知道在这种情况下,“消费者”可能会在没有任何通知的情况下醒来,因此等待需要检查谓词。
但是等待谓词如何解决“丢失唤醒”的问题?正如您在下面的代码中看到的那样; 'wait' 没有被调用 5 秒,我预计它会错过前几个通知;但早于,它不会错过任何。这些通知是否已保存以供将来等待?
#include <iostream>
#include <deque>
#include <condition_variable>
#include <thread>
std::deque<int> q;
std::mutex m;
std::condition_variable cv;
void dump_q()
{
for (auto x: q) {
std::cout << x << std::endl;
}
}
void producer()
{
for(int i = 0; i < 10; i++) {
std::unique_lock<std::mutex> locker(m);
q.push_back(i);
std::cout << "produced: " << i << std::endl;
cv.notify_one();
std::this_thread::sleep_for(std::chrono::seconds(1));
locker.unlock();
}
}
void consumer()
{
while (true) {
int data = 0;
std::this_thread::sleep_for(std::chrono::seconds(5)); // <- should miss first 5 notications?
std::unique_lock<std::mutex> locker(m);
cv.wait(locker);
//cv.wait(locker, [](){return !q.empty();}); // <- this fixes both spurious and lost wakeups
data = q.front();
q.pop_front();
std::cout << "--> consumed: " << data << std::endl;
locker.unlock();
}
}
int main(int argc, char *argv[])
{
std::thread t1(producer);
std::thread t2(consumer);
t1.join();
t2.join();
return 0;
}
【问题讨论】:
标签: c++ multithreading synchronization race-condition condition-variable