C++ 与std::condition\u variable\u any相关的开销是多少

C++ 与std::condition\u variable\u any相关的开销是多少,c++,multithreading,c++11,mutex,condition-variable,C++,Multithreading,C++11,Mutex,Condition Variable,我在很多地方都读到过,有一些开销与std::condition\u variable\u any有关。只是想知道,这是什么开销 我的猜测是,由于这是一个通用的条件变量,可以处理任何类型的锁,它需要一个手动滚动的等待实现(可能使用另一个条件变量和互斥或futex,或类似的东西),所以额外的开销可能来自于此?但不确定。。。而不仅仅是pthread\u cond\u wait()(以及其他系统上的等价物)等的本机包装器 接下来,如果我要说的是实现等待的东西,比如说共享互斥,那么由于性能开销,这种类型

我在很多地方都读到过,有一些开销与
std::condition\u variable\u any
有关。只是想知道,这是什么开销

我的猜测是,由于这是一个通用的条件变量,可以处理任何类型的锁,它需要一个手动滚动的等待实现(可能使用另一个条件变量和互斥或futex,或类似的东西),所以额外的开销可能来自于此?但不确定。。。而不仅仅是
pthread\u cond\u wait()
(以及其他系统上的等价物)等的本机包装器


接下来,如果我要说的是实现等待的东西,比如说共享互斥,那么由于性能开销,这种类型的条件变量是一个错误的选择吗?在这种情况下我还能做什么?

pthread\u cond\u wait()
/
SleepConditionVariableSRW()
,与普通的
std::condition\u variable::wait()
一样,只需要一个原子系统调用就可以释放互斥锁、等待条件变量和重新获取互斥锁。线程立即进入睡眠状态,另一个线程(理想情况下是被互斥锁阻塞的线程)可以立即接管同一个内核

使用
std::condition\u variable\u any
,对传递的
BasicLockable
进行解锁并开始等待本机事件/条件不仅仅是一个系统调用,它首先调用
BasicLockable
上的
unlock()
方法,然后才发出等待的系统调用。因此,您至少有来自单独的
unlock()
的开销,而且您更有可能在操作系统端触发一个不太理想的调度决策。最糟糕的情况是,解锁甚至会导致另一个内核上的等待线程继续运行,并带来所有相关开销

另一方面,例如,在伪唤醒上,在处理本机互斥(如
std::mutex
中使用的)时,也可以进行操作系统端调度优化,而本机互斥不适用于通用的
基本时钟

两者都涉及一些簿记,以便提供
notify_all()
逻辑(实际上每个等待线程只有一个事件/条件)以及保证所有方法都是原子的,因此它们都会带来少量开销


真正的开销来自操作系统对组合信号和等待锁定系统调用做出良好调度决策的能力。如果操作系统在调度方面不聪明,那么它几乎没有什么区别。

为什么你必须猜测至少两个主要实现的源代码何时可以免费使用?如果你需要
条件变量\u any
的功能,你就需要它。否则,如果需要,请使用普通的
条件变量
。我们不可能想出一个标准库实现者没有想到的简单而极快的方法。在vc++上,有一个开销——cv_any在共享ptr上分配它的状态,当你等待它时,它复制指针,锁定你的给定锁和它自己的内部创建锁。但是如上所述,如果您需要cv_any,我想没有办法了。@DavidHaim在理解这一点时遇到了一些困难,为什么锁必须包装在共享的_ptr中?锁的生存期应该在条件变量的生存期之前有效,对吗?为什么要延长它的生存期?因为由于[thread.condition.condvarany]/5,互斥锁(“lock”)需要比条件变量更有效。