【转】pthread_cond_signal 虚假唤醒问题

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

什么是虚假唤醒?

举个例子,咱们如今有一个生产者-消费者队列和三个线程。spa

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

使用while()判断的缘由

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

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

相关文章
相关标签/搜索