我们知道条件变量会受到虚假唤醒的影响。假设我们有一个1-producer-1-consumer队列与互斥和条件变量同步。消费者线程得到了虚假的唤醒。 问题是 - 消费者线程是否会错过来自生产者的通知信号? 我理解它极不可能......但是仍然有可能丢失队列中的最后一个元素吗?
答案 0 :(得分:2)
如果调用lock the mutex
while the condition is not satisfied
wait on the condition variable
的代码没有写好,那么它确实会错过唤醒。但那会有点不正常。通常的习语是:
lock the mutex
signal the condition variable
信令线程应该在发信号之前锁定互斥锁:
matplotlib
等待条件变量会在等待期间解锁互斥锁。但是,当等待调用返回时,互斥锁将被锁定。因此,在虚假唤醒时,等待线程将保持互斥锁,直到它恢复等待。当等待线程保持互斥锁时,信令线程不能发信号通知条件变量。当等待线程实际等待时,互斥锁被解锁并且信令线程可以继续并发出信号;等待线程将获取信号,一旦信令线程释放互斥锁,等待线程将继续执行。
所以,不,正确的代码不会错过信号。但是如果等待线程释放互斥锁并在检查其状态的过程中重新获取它,则信号可能在等待线程调用等待之前发生,并且信号将丢失。不要这样做。 &LT g取代;
答案 1 :(得分:1)
虚假醒来意味着它可能会虚假地醒来然后不得不继续等待。
它根本没有提到错过事件的可能性,因为如果这是真的就没用了。
此链接提供了cv和等待方法的详细说明:
https://www.codeproject.com/Articles/598695/Cplusplus-threads-locks-and-condition-variables
// print a starting message
{
std::unique_lock<std::mutex> locker(g_lockprint);
std::cout << "[logger]\trunning..." << std::endl;
}
// loop until end is signaled
while(!g_done)
{
std::unique_lock<std::mutex> locker(g_lockqueue);
g_queuecheck.wait(locker, [&](){return !g_codes.empty();});
// if there are error codes in the queue process them
while(!g_codes.empty())
{
std::unique_lock<std::mutex> locker(g_lockprint);
std::cout << "[logger]\tprocessing error: " << g_codes.front() << std::endl;
g_codes.pop();
}
}