c ++标准库中的许多类现在都有移动构造函数,例如 -
thread::thread(thread&& t)
Run Code Online (Sandbox Code Playgroud)
但似乎std :: mutex没有.我知道它们不能被复制,但是能够从"make_mutex"函数中返回一个似乎是有意义的.(不是说它有用,只是它有意义)
有什么理由说std :: mutex没有移动构造函数吗?
seh*_*ehe 40
嗯......主要是因为我认为他们不应该动.从字面上看.
在某些操作系统中,互斥锁可能被建模为句柄(因此您可以复制它们)但是IIRC会对pthreads互斥锁进行就地操作.如果要重新定位,那么任何线程安全都会立即飞出窗口(其他线程如何知道互斥锁刚刚改变了它的内存地址......)?
Luc*_*ton 17
请记住,C++将"不为你不使用的东西付钱"的理念铭记于心.让我们考虑一个假想的平台,它使用opaque类型来表示互斥体; 我们称之为那种类型mutex_t.如果在该互斥锁上操作的接口mutex_t*用作参数,例如像void mutex_init(mutex_t* mutex);"构造"互斥锁一样,那么互斥锁的地址可能就是用于唯一标识互斥锁的情况.如果是这种情况,则表示mutex_t不可复制:
mutex_t kaboom()
{
mutex_t mutex;
mutex_init(&mutex);
return mutex; // disaster
}
Run Code Online (Sandbox Code Playgroud)
这样做时mutex_t mutex = kaboom();,无法保证与功能块中的&mutex值相同&mutex.
当一天实现者想要std::mutex为该平台编写一个实现者时,如果该类型的要求是可移动的,那么这意味着内部mutex_t必须放置在动态分配的内存中,并具有所有相关的惩罚.
在另一方面,虽然现在std::mutex是不是可移动的,它很容易从一个函数"回归"之一:返回一个std::unique_ptr<std::mutex>代替.这仍然支付动态分配的成本,但仅在一个地方.所有其他不需要移动的代码都不需要std::mutex付费.
换句话说,因为移动互斥锁不是互斥锁的核心操作,不需要std::mutex移动就不会移除任何功能(由于不可移动 T => 可移动 std::unique_ptr<T>转换)并且将产生最小的开销成本直接使用本机类型.
std::thread可能已被类似地指定为不可移动,这将使得典型的生命周期如下:在调用有价值的构造函数之后运行(与执行的线程相关联); 在调用join或之后,分离/加入(与没有执行的线程相关联)detach.根据我的理解,它std::vector<std::thread>仍然可用,因为类型本来可以EmplaceConstructible.
编辑:不正确!该类型仍然需要移动(毕竟重新分配时).所以对我来说这是不够的理由:这是典型的投入std::thread到像容器std::vector和std::deque,这样的功能是值得欢迎的那种类型.
| 归档时间: |
|
| 查看次数: |
11435 次 |
| 最近记录: |