Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::条件变量::带谓词的等待_C++_Multithreading_C++11_Std_Condition Variable - Fatal编程技术网

C++ std::条件变量::带谓词的等待

C++ std::条件变量::带谓词的等待,c++,multithreading,c++11,std,condition-variable,C++,Multithreading,C++11,Std,Condition Variable,在std::condition_变量的文档中,有一个wait()重载,将参数作为谓词函数。该函数将一直等到谓词函数为true的第一次唤醒 在 据称,这相当于: while (!pred()) { wait(lock); } 而且: 在等待特定条件变为真时,此重载可用于忽略虚假唤醒。请注意,在进入此方法之前,必须获取锁,在等待(锁)退出后,也会重新获取锁,即锁可以用作pred()访问的保护 我不太清楚,这些是严格等效的(在这种情况下,我更喜欢简单的while循环,它比在我的情况下使用la

在std::condition_变量的文档中,有一个wait()重载,将参数作为谓词函数。该函数将一直等到谓词函数为true的第一次唤醒

据称,这相当于:

while (!pred()) {
    wait(lock);
}
而且:

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

我不太清楚,这些是严格等效的(在这种情况下,我更喜欢简单的while循环,它比在我的情况下使用lambda重载更容易阅读),还是重载(可能取决于实现)更有效

在唤醒等待的线程之前,实现能否在通知线程中评估谓词,以避免在测试条件为false时唤醒?这里需要C++线程大师……/P>
谢谢

据我所知,这两个(a
循环和
等待+谓词
)在功能上是等价的。如果在循环过程中使用
,则在第一次输入和评估循环条件之前应获取锁。每隔一段时间,您也会持有锁,因为
predicate()
将在
wait()
完成后执行

重载在内部执行相同的操作:您必须在调用
wait
之前获取锁,在等待完成后,将在内部调用
谓词()
,以检查是否应该继续等待(就像while循环所做的那样)


也许您是对的,对于使用
返回
布尔值的简单谓词,而
循环更清晰。但是如果
谓词
变得更复杂怎么办?为它定义一个专用函数,并在while循环条件下使用它,还是就地使用lambda?如果谓词数量增加,您会为每个谓词定义函数吗?在我看来,在本例中使用lambdas可以使代码更加清晰,因为整个内容都保存在一个逻辑单元中

实现可以尝试从性能角度使其优于循环,但我怀疑这是可能的。这是非常严格的,您可以检查您的实现,看看它是如何完成的。这就是gcc 4.9.2在这里所做的:

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

这就是我对该功能目的的理解。但是从文档中,我了解到重载可以避免在变量没有改变的情况下唤醒线程。这意味着在有效地唤醒等待的线程之前,谓词对象在另一个线程(例如通知线程)中进行求值。因此更efficient@galinette不,它不能。它基于pthread条件变量,这些条件变量确实有虚假的唤醒。该标准不基于pthread,也不基于所有实现。如果我是对的,windows线程在这方面比pthreads有更多的可能性(因为我使用的是mingw gcc,我有选择权)@galinette,standard当然从来没有这样说过。但如果比较两个API,这是显而易见的。特别是,MingWGCC使用mingw提供的与Posix兼容的包装(mingwthrd或类似的东西),所以在gcc看来,它就是Posix。
cond_var.wait(lock, []() { return bool_var == true; })