2016-07-06 43 views
2

为什么condition_variable不是MoveConstructible(按照http://en.cppreference.com/w/cpp/thread/condition_variable)?这禁止包含在大量移动东西的容器中(例如std::unordered_map)。为什么一个condition_variable不是MoveAssignable

这迫使人们使用一个unique_ptr这引起了一个额外的堆分配,其中像make_shared这样的东西是建立来解决。此外,如果没有池分配器,这可能变得非常低效。

+0

可能让线程安全太麻烦。您不希望在移动变量期间发生通知。 – NathanOliver

+0

@NathanOliver反正'condition_variable'线程的接口中的所有函数都不安全吗?我只是想着为什么这应该是一个问题 – Curious

+0

我认为这只是没有任何意义。考虑一个条件变量处于等待状态并且另一个线程复制它的情况。复制的条件变量的状态应该是什么?如果你说它应该像它的默认构建状态那么再次复制真的没有意义。此外,它取决于是否允许在不调用UB的情况下复制本地条件变量结构(用于'std :: condition_variable')是否允许复制'pthread_cond_t'。 – Arunmu

回答

4

condition_variable是多线程(可能)同时使用的同步构造。 (事实上​​,这是它的目的。)你怎么能安全地移动它?例如,假设它直接包含自旋锁。一些线程正在您的进程地址空间中的给定地址上旋转,并且您将要将对象从其下移出?

任何种类的用户模式同步构造都不能移动。实际同步需要固定地址。你可以强制这个对象在一个不会被移动的堆分配对象上完成它所有的实际工作 - 并且你直接去间接寻找你想要避免的堆。 (内核模式同步结构可以移动:你有一些操作系统的东西,但是它们的价格要高得多使用。)

它们不能被复制 - 因为那会是什么意思?

它只是这样。你的设计必须解释它,就是这样。

(我并不真正理解你的问题的第二段,make_shared是为了让ref计数更便宜而且没有任何与移动东西有关的东西。池分配器可能会也可能不会提高特别的情况,更不用说这个了,除非你测量它,否则你就不会知道。)