aka*_*okd 203 java multithreading locking spurious-wakeup
看到各种锁定相关的问题和(几乎)总是找到'循环因为虚假的唤醒'术语1我想知道,有没有人经历过这样的唤醒(假设一个像样的硬件/软件环境)?
我知道"虚假"一词意味着没有明显的理由,但这种事件的原因是什么?
(1注意:我不是在质疑循环练习.)
编辑:一个帮助问题(对于那些喜欢代码示例的人):
如果我有以下程序,我运行它:
public class Spurious {
public static void main(String[] args) {
Lock lock = new ReentrantLock();
Condition cond = lock.newCondition();
lock.lock();
try {
try {
cond.await();
System.out.println("Spurious wakeup!");
} catch (InterruptedException ex) {
System.out.println("Just a regular interrupt.");
}
} finally {
lock.unlock();
}
}
}
Run Code Online (Sandbox Code Playgroud)
await
如果不等待随机事件,我该怎么做才能虚假地唤醒它?
Joh*_*ica 198
pthread_cond_wait()
Linux中的功能是使用futex
系统调用实现的.EINTR
当进程收到信号时,Linux上的每个阻塞系统调用都会突然返回....pthread_cond_wait()
无法重新启动等待,因为它可能会在futex
系统调用之外的一小段时间内错过真正的唤醒.只有呼叫者检查不变量才能避免这种竞争条件.因此,POSIX信号将产生虚假唤醒.
简介:如果发出一个Linux进程的信号,它的等待线程将各自享受一个不错的,热的虚假唤醒.
我买它.这是一个比通常模糊的"性能"原因更容易吞下的药丸.
Mr.*_*rdy 22
我有一个展示这种行为的生产系统.线程等待队列中有消息的信号.在繁忙时期,高达20%的唤醒是虚假的(即当它唤醒时,队列中没有任何内容).该线程是消息的唯一消费者.它运行在Linux SLES-10 8处理器盒上,使用GCC 4.1.2构建.这些消息来自外部源并且是异步处理的,因为如果我的系统没有足够快地读取它们就会出现问题.
Ani*_*kur 13
回答titile中的问题 - 是的!它确实发生了.尽管维基文章提到了一个关于虚假唤醒的大量信息,但我遇到的一个很好的解释如下 -
想一想......就像任何代码一样,线程调度程序可能会因底层硬件/软件中发生异常而暂时停电.当然,应该注意尽可能少地发生这种情况,但是由于没有100%强大的软件这样的事情,所以假设这种情况可能发生并且在调度程序检测到这种情况时要注意优雅恢复是合理的(例如,通过观察失踪的心跳).
现在,调度程序如何恢复,考虑到在停电期间它可能会错过一些旨在通知等待线程的信号?如果调度程序什么都不做,那么提到的"不幸"线程就会挂起,永远等待 - 为了避免这种情况,调度程序只会向所有等待的线程发送一个信号.
这使得有必要建立一个"合同",即无需理由就可以通知等待线程.确切地说,有一个原因 - 调度程序停电 - 但由于线程被设计(有充分理由)无法调度内部实现细节,因此这个原因可能更好地表现为"虚假".
我正在从Source阅读这个答案,并认为它足够合理.还看了
PS:以上链接是我的个人博客,其中包含有关虚假唤醒的其他详细信息.
只是添加这个.是的,它发生了,我花了三天时间在24核计算机(JDK 6)上搜索多线程问题的原因.10次执行中有4次没有任何模式.这从未发生在2核或8核上.
研究了一些在线资料,这不是Java问题,而是一种罕见但预期的行为.
归档时间: |
|
查看次数: |
32245 次 |
最近记录: |