面试常考点:虚假唤醒 Spurious wakeup
2015-08-01 15:35
751 查看
https://en.wikipedia.org/wiki/Spurious_wakeup
Spurious wakeup describes a complication in the use of condition
variables as provided by certain multithreading APIs such
as POSIX Threads and the Windows
API.
Even after a condition variable appears to have been signaled from a waiting thread's point of view, the condition that was awaited may still be false. One of the reasons for this is a spurious wakeup; that is, a thread might be awoken from its waiting state
even though no thread signaled the condition variable. For correctness it is necessary, then, to verify that the condition is indeed true after the thread has finished waiting. Because spurious wakeup can happen repeatedly, this is achieved by waiting inside
a loop that terminates when the condition is true, for example:
In this example it is known that another thread will set buf->full (the actual condition awaited) before signaling buf->cond (the means of synchronizing the two threads). The waiting thread will always verify the truth of the actual condition upon returning
from
According to David R. Butenhof's Programming with POSIX Threads ISBN
0-201-63392-2:
"This means that when you wait on a condition variable, the wait may (occasionally) return when no thread specifically broadcast or signaled that condition variable. Spurious wakeups may sound
strange, but on some multiprocessor systems, making condition wakeup completely predictable might substantially slow all condition variable operations. The race
conditions that cause spurious wakeups should be considered rare."
http://siwind.iteye.com/blog/1469216
虚假唤醒(spurious wakeup)在采用条件等待时,我们使用的是
Java代码
while(条件不满足){
condition_wait(cond, mutex);
}
而不是:
If( 条件不满足 ){
Condition_wait(cond,mutex);
}
这是因为可能会存在虚假唤醒”spurious wakeup”的情况。
也就是说,即使没有线程调用condition_signal, 原先调用condition_wait的函数也可能会返回。此时线程被唤醒了,但是条件并不满足,这个时候如果不对条件进行检查而往下执行,就可能会导致后续的处理出现错误。
虚假唤醒在linux的多处理器系统中/在程序接收到信号时可能回发生。在Windows系统和JAVA虚拟机上也存在。在系统设计时应该可以避免虚假唤醒,但是这会影响条件变量的执行效率,而既然通过while循环就能避免虚假唤醒造成的错误,因此程序的逻辑就变成了while循环的情况。
注意:即使是虚假唤醒的情况,线程也是在成功锁住mutex后才能从condition_wait()中返回。即使存在多个线程被虚假唤醒,但是也只能是一个线程一个线程的顺序执行,也即:lock(mutex) 检查/处理 condition_wai()或者unlock(mutex)来解锁.
Spurious wakeup describes a complication in the use of condition
variables as provided by certain multithreading APIs such
as POSIX Threads and the Windows
API.
Even after a condition variable appears to have been signaled from a waiting thread's point of view, the condition that was awaited may still be false. One of the reasons for this is a spurious wakeup; that is, a thread might be awoken from its waiting state
even though no thread signaled the condition variable. For correctness it is necessary, then, to verify that the condition is indeed true after the thread has finished waiting. Because spurious wakeup can happen repeatedly, this is achieved by waiting inside
a loop that terminates when the condition is true, for example:
/* In any waiting thread: */ while(!buf->full) wait(&buf->cond, &buf->lock); /* In any other thread: */ if(buf->n >= buf->size){ buf->full = 1; signal(&buf->cond); }
In this example it is known that another thread will set buf->full (the actual condition awaited) before signaling buf->cond (the means of synchronizing the two threads). The waiting thread will always verify the truth of the actual condition upon returning
from
wait, ensuring correct behaviour if spurious wakeup occurs.
According to David R. Butenhof's Programming with POSIX Threads ISBN
0-201-63392-2:
"This means that when you wait on a condition variable, the wait may (occasionally) return when no thread specifically broadcast or signaled that condition variable. Spurious wakeups may sound
strange, but on some multiprocessor systems, making condition wakeup completely predictable might substantially slow all condition variable operations. The race
conditions that cause spurious wakeups should be considered rare."
http://siwind.iteye.com/blog/1469216
虚假唤醒(spurious wakeup)在采用条件等待时,我们使用的是
Java代码
while(条件不满足){
condition_wait(cond, mutex);
}
而不是:
If( 条件不满足 ){
Condition_wait(cond,mutex);
}
这是因为可能会存在虚假唤醒”spurious wakeup”的情况。
也就是说,即使没有线程调用condition_signal, 原先调用condition_wait的函数也可能会返回。此时线程被唤醒了,但是条件并不满足,这个时候如果不对条件进行检查而往下执行,就可能会导致后续的处理出现错误。
虚假唤醒在linux的多处理器系统中/在程序接收到信号时可能回发生。在Windows系统和JAVA虚拟机上也存在。在系统设计时应该可以避免虚假唤醒,但是这会影响条件变量的执行效率,而既然通过while循环就能避免虚假唤醒造成的错误,因此程序的逻辑就变成了while循环的情况。
注意:即使是虚假唤醒的情况,线程也是在成功锁住mutex后才能从condition_wait()中返回。即使存在多个线程被虚假唤醒,但是也只能是一个线程一个线程的顺序执行,也即:lock(mutex) 检查/处理 condition_wai()或者unlock(mutex)来解锁.
相关文章推荐
- 黑马程序员——15,String,StringBuffer,基本数据类型包装对象
- 剑指Offer面试题15(Java版):链表中倒数第K个结点
- 黑马程序员—— 反射总结
- 【剑指Offer面试题】 九度OJ1523:从上往下打印二叉树
- 黑马程序员——java学习9(毕15-16)——TreeSet、Map、泛型、字符排序
- 怎样才是理想的程序员
- 黑马程序员——多线程知识总结1
- 【练习笔记】剑指offer-面试题6 :重建二义树
- 黑马程序员------TreeSet集合框架存储自定义元素之排序Comparable与Comparator
- 黑马程序员-------集合框架之Collection
- 程序员必读书单
- 剑指offer面试题14(Java版):调整数组顺序使奇数位于偶数的前面
- 【练习笔记】剑指offer-面试题5 :从尾到头打印链表
- 黑马程序员——字符串常见操作
- 每个程序员和设计师必做的10项运动
- 黑马程序员——OC类方法
- 【练习笔记】剑指offer-面试题4 :替换空格
- 面试30 求数组中最小的k个数
- 看不惯别人
- 黑马程序员---iOS基础---OC中类创建对象