当前位置:  开发笔记 > 编程语言 > 正文

增强线程中的虚假解除阻塞

如何解决《增强线程中的虚假解除阻塞》经验,为你挑选了1个好方法。

我今天在Boost线程文档中遇到了这个有趣的段落:

void wait(boost::unique_lock& lock)

...

效果:原子调用lock.unlock()并阻止当前线程.当通过调用this-> notify_one()或this-> notify_all()或虚假地通知时,线程将解除阻塞.当线程被解除阻塞(无论出于何种原因)时,通过在等待调用返回之前调用lock.lock()来重新获取锁.如果函数以异常退出,则还可以通过调用lock.lock()来重新获取锁.

所以我感兴趣的是"虚假地"这个词的含义.为什么线程会因为虚假原因而被解除阻塞?可以做些什么来解决这个问题?



1> 1800 INFORMA..:

Anthony Williams的这篇文章特别详细.

无法预测虚假的醒来:从用户的角度来看,它们基本上是随机的.但是,它们通常在线程库无法可靠地确保等待线程不会错过通知时发生.由于错过的通知会使条件变量无效,因此线程库会从等待中唤醒线程而不是冒险.

他还指出,您不应该使用timed_wait持续时间的重载,并且通常应该使用带谓词的版本

这是初学者的错误,并且可以通过一个简单的规则轻松克服:在等待条件变量时,总是在循环中检查谓词.更阴险的bug来自timed_wait().

弗拉基米尔普鲁斯的这篇文章也很有趣.

但是为什么我们需要while循环,我们不能写:

if (!something_happened)
  c.wait(m);

我们做不到.而杀手的原因是"等待"可以在没有任何"通知"电话的情况下返回.这称为虚假唤醒,POSIX明确允许.实质上,从"等待"返回仅表示共享数据可能已更改,因此必须再次评估数据.

好的,为什么这还没有修好呢?第一个原因是没有人想要解决它.由于其他几个原因,非常需要在循环中包含对"等待"的调用.但是这些原因需要解释,而虚假的唤醒是一把锤子,可以毫无疑问地应用于任何一年级学生.

推荐阅读
oDavid_仔o_880
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有