繁体   English   中英

std :: condition_variable :: with谓词等待

[英]std::condition_variable::wait with predicate

在std :: condition_variable的文档中,使用谓词函数作为参数的wait()重载。 该函数将一直等到谓词函数为true的第一次wake_up。

文档中

据说这相当于:

while (!pred()) {
    wait(lock);
}

但是也:

在等待特定条件变为真时,可以使用此重载来忽略虚假唤醒。 请注意,在进入此方法之前,必须先获取锁,在wait(lock)退出后也必须重新获取它,即锁可以用作pred()访问的保护。

我不确定要理解的是,这些严格地等效吗(在这种情况下,我更喜欢普通的while循环,比我的情况下带有lambda的重载更容易阅读),或者重载(可能取决于实现)更有效?

为了避免测试条件为假时唤醒,实现是否可以在唤醒等待线程之前评估通知线程中的谓词? 这里需要c ++线程大师...

谢谢

从性能的角度来看,实现可以尝试使其比循环更好,但是我怀疑这样做是否可行。 这是非常严格的,您可以检查实现以查看完成情况。 这就是gcc 4.9.2在这里所做的:

template<typename _Predicate>
  void
  wait(unique_lock<mutex>& __lock, _Predicate __p)
  {
      while (!__p())
        wait(__lock);
  }

如您所见,它是完全一样的,我怀疑是否可以在此做其他事情。 至于可读性,它比循环更具可读性。 但是,您可能会误解其原因。 该循环仅用于检查由条件保证的实变量确实确实更改为您期望的值-可能没有。 常见的代码片段如下所示:

cond_var.wait(lock, []() { return bool_var == true; })

据我了解,这两个( while循环和wait + predicate )在功能上是等效的。 如果要使用while循环,则应在首次进入并评估循环条件之前获取锁定。 每隔两次您还将持有该锁,因为predicate()将在wait()完成后执行。

内部重载的作用相同:您必须在调用wait之前获取锁定,并且在wait完成之后,内部调用predicate()来检查是否应继续等待(就像while循环一样)。

对于简单谓词,使用while循环返回boolean值更加清晰,也许您是对的。 但是如果predicate变得更复杂怎么办? 为它定义一个专用函数并在while循环条件下使用它,还是在原处使用lambda? 如果谓词数量增加,您将为每个谓词定义功能吗? 在我看来,在这种情况下使用lambda可以使代码更清晰,因为整个事物都放在一个逻辑单元中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM