我在今天提升线程文档

void wait(boost::unique_lock<boost::mutex>& lock)

...

  

效果:原子调用lock.unlock()   并阻止当前线程。该   线程将在通知时解除阻止   请致电此&gt; notify_one()或   this-&gt; notify_all()或虚假。   线程解除阻塞时(for   无论什么原因),锁是   通过调用lock.lock()重新获取   在等待调用之前返回。该   也可以通过调用重新获取锁   lock.lock()如果函数退出   例外。

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

有帮助吗?

解决方案

Anthony Williams的这篇文章特别详细

  

无法预测虚假的醒来:   他们基本上是随机的   用户的观点。但是,他们   通常在线程库时发生   不能可靠地保证一个等待   线程不会错过通知。   由于错过了通知   渲染条件变量无用,   线程库唤醒线程   从等待而不是采取   风险。

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

  

这是初学者的错误,还有一个   这很容易通过简单的方法克服   规则:总是检查你的谓词   等待条件时循环   变量。更阴险的错误来了   来自timed_wait()。

Vladimir Prus的这篇文章也很有趣。

  

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

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

我们做不到。而杀手的原因是'等待'可以   没有任何'通知'电话返回。   那被称为虚假唤醒而且是   POSIX明确允许。   基本上,只从“等待”返回   表示共享数据可能   已经改变了,所以必须有数据   再次评估。

     

好的,为什么这还没有修好呢?   第一个原因是没有人想要   要解决这个问题。打电话给“等待”   一些循环非常需要几个   其他原因。但那些原因   需要解释,而虚假   唤醒是一种可以应用的锤子   没有的任何一年级学生   失败。

其他提示

这篇博客文章给出了Linux的理由,就其而言当信号传递给进程时返回的 futex 系统调用。不幸的是,它没有解释任何其他内容(实际上是要求更多信息)。

维基百科关于虚假唤醒的条目(这似乎是一个posix范围的概念,顺便说一句,不仅限于提升)也可能对你感兴趣。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top