pthread_cond_signal 虚假唤醒问题

Posted uangyy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pthread_cond_signal 虚假唤醒问题相关的知识,希望对你有一定的参考价值。

引用:http://blog.csdn.net/leeds1993/article/details/52738845

什么是虚假唤醒?

举个例子,我们现在有一个生产者-消费者队列和三个线程。

I.1号线程从队列中获取了一个元素,此时队列变为空。 
II.2号线程也想从队列中获取一个元素,但此时队列为空,2号线程便只能进入阻塞(cond.wait()),等待队列非空。 
III.这时,3号线程将一个元素入队,并调用cond.notify()唤醒条件变量。 
IV.处于等待状态的2号线程接收到3号线程的唤醒信号,便准备解除阻塞状态,执行接下来的任务(获取队列中的元素)。 
V.然而可能出现这样的情况:当2号线程准备获得队列的锁,去获取队列中的元素时,此时1号线程刚好执行完之前的元素操作,返回再去请求队列中的元素,1号线程便获得队列的锁,检查到队列非空,就获取到了3号线程刚刚入队的元素,然后释放队列锁。 
VI.等到2号线程获得队列锁,判断发现队列仍为空,1号线程“偷走了”这个元素,所以对于2号线程而言,这次唤醒就是“虚假”的,它需要再次等待队列非空。

使用while()判断的原因

在多核处理器下,pthread_cond_signal可能会激活多于一个线程(阻塞在条件变量上的线程)。结果就是,当一个线程调用pthread_cond_signal()后,多个调用pthread_cond_wait()或pthread_cond_timedwait()的线程返回。这种效应就称为“虚假唤醒”。

注:pthread_cond_wait这个函数是单个原子操作,即这个函数的两个动作:解锁 && 进入block 是一个原子操作。

以上是关于pthread_cond_signal 虚假唤醒问题的主要内容,如果未能解决你的问题,请参考以下文章

Java多线程虚假唤醒问题(生产者和消费者关系)

《C++ 并发编程实战 第二版》:条件变量唤醒丢失与虚假唤醒

《C++ 并发编程实战 第二版》:条件变量唤醒丢失与虚假唤醒

wait/notify之虚假唤醒

std::future::wait_for 虚假唤醒?

wait notify之虚假唤醒