我有一个由几个'块'组成的数据结构。对于每个块我都有互斥。我想实现一个锁定整个数据结构并将此锁移动到调用函数的方法。这是我的代码:
std::vector<std::unique_lock<boost::shared_mutex>> lock_array()
{
std::vector<std::unique_lock<boost::shared_mutex>> locks;
for(size_t block = 0; block < BLOCK_COUNT; ++block)
{
locks.push_back(std::unique_lock<boost::shared_mutex>(mutexes[block]));
}
return std::move(locks);
}
如果我以这种方式调用它,我的阵列是否仍会被锁定?
void some_method()
{
auto locks = lock_array();
...
}
答案 0 :(得分:3)
是。移动unique_lock
将保留锁定,移动向量不应影响锁定。你可以验证一下:
void some_method()
{
auto locks = lock_array();
for (auto const & lock : locks) {
assert(lock.owns_lock());
}
}
另请注意,返回时不需要std::move
;无论如何都要移动返回值(除非移动被省略)。
答案 1 :(得分:1)
您已将locks
移出lock_array()
函数,编译器应使用RVO或移动锁定lock_array()
,否则您将获得编译器错误,因为unique_lock是可移动的但不可复制。
锁仍然锁定,因为它们在构造期间获得锁定,并且仅在锁超出范围时才会销毁。您的转移操作不会破坏锁定。
§30.4.2.2
unique_lock类型的对象控制范围内可锁定对象的所有权。 可锁定对象的所有权可以在构造时或在构造之后获取,并且可以在获取之后被转移到另一个unique_lock对象。 unique_lock类型的对象不可复制,但可以移动。