std::unique_lock 移动语义
std::unique_lock move semantic
请帮我看看我对std::unique_lock
移动语义的理解是否正确。
假设我有一个函数 myFunc
需要在其执行开始时获取互斥量。
这个函数是从不同的函数调用的,其中一些函数例如myWrapper1
在 myFunc
调用之前保持相同的互斥锁。
有时我需要在 myFunc
的范围退出时不释放此锁。
typedef std::unique_lock<std::mutex> MyLock;
class Example2
{
std::mutex m_data_mutex;
MyLock&& myFunc(MyLock&& lk)
{
bool was_lock = lk.owns_lock();
if( !was_lock ) lk.lock();
std::cout << "myFunc" << std::endl;
if( !was_lock ) lk.unlock();
return std::move(lk);
}
void myWrapper1()
{
MyLock lk(m_data_mutex);
std::cout << "1" << std::endl;
lk = myFunc(std::move(lk));
std::cout << "2" << std::endl;
}
void myWrapper2()
{
MyLock lk(m_data_mutex);
std::cout << "1" << std::endl;
lk.unlock();
lk = myFunc(std::move(lk));
std::cout << "2" << std::endl;
lk.lock();
std::cout << "3" << std::endl;
}
};
所以问题是:
- 对于
myWrapper1
可以保证 MyLock
只会在 myWrapper1
作用域结束时被释放,不是吗?
- 我对这道题的习语是否正确?
你有什么理由不能做这样的事情吗? IMO,这比在所有者之间移动锁要干净得多。
std::mutex my_lock;
void myFunc_locked() {
...do something that requires my_lock to be locked...
}
void myFunc() {
std::lock_guard<std::mutex> guard(my_lock);
myFunc_locked();
}
void myWrapper1() {
std::lock_guard<std::mutex> guard(my_lock);
...do something else that requires my_lock to be locked...
myFunc_locked();
}
void myWrapper2() {
...
myFunc();
}
或者,按照@Nevin 的建议进行操作。也许更干净:
std::mutex my_lock;
void myFunc(std::lock_guard<std::mutex>> const& guard) {
...do something that requires my_lock to be locked...
}
void myFunc() {
std::lock_guard<std::mutex> guard(my_lock);
myFunc(guard);
}
void myWrapper1() {
std::lock_guard<std::mutex> guard(my_lock);
...do something else that requires my_lock to be locked...
myFunc(guard);
}
void myWrapper2() {
...
myFunc();
}
请帮我看看我对std::unique_lock
移动语义的理解是否正确。
假设我有一个函数 myFunc
需要在其执行开始时获取互斥量。
这个函数是从不同的函数调用的,其中一些函数例如myWrapper1
在 myFunc
调用之前保持相同的互斥锁。
有时我需要在 myFunc
的范围退出时不释放此锁。
typedef std::unique_lock<std::mutex> MyLock;
class Example2
{
std::mutex m_data_mutex;
MyLock&& myFunc(MyLock&& lk)
{
bool was_lock = lk.owns_lock();
if( !was_lock ) lk.lock();
std::cout << "myFunc" << std::endl;
if( !was_lock ) lk.unlock();
return std::move(lk);
}
void myWrapper1()
{
MyLock lk(m_data_mutex);
std::cout << "1" << std::endl;
lk = myFunc(std::move(lk));
std::cout << "2" << std::endl;
}
void myWrapper2()
{
MyLock lk(m_data_mutex);
std::cout << "1" << std::endl;
lk.unlock();
lk = myFunc(std::move(lk));
std::cout << "2" << std::endl;
lk.lock();
std::cout << "3" << std::endl;
}
};
所以问题是:
- 对于
myWrapper1
可以保证MyLock
只会在myWrapper1
作用域结束时被释放,不是吗? - 我对这道题的习语是否正确?
你有什么理由不能做这样的事情吗? IMO,这比在所有者之间移动锁要干净得多。
std::mutex my_lock;
void myFunc_locked() {
...do something that requires my_lock to be locked...
}
void myFunc() {
std::lock_guard<std::mutex> guard(my_lock);
myFunc_locked();
}
void myWrapper1() {
std::lock_guard<std::mutex> guard(my_lock);
...do something else that requires my_lock to be locked...
myFunc_locked();
}
void myWrapper2() {
...
myFunc();
}
或者,按照@Nevin 的建议进行操作。也许更干净:
std::mutex my_lock;
void myFunc(std::lock_guard<std::mutex>> const& guard) {
...do something that requires my_lock to be locked...
}
void myFunc() {
std::lock_guard<std::mutex> guard(my_lock);
myFunc(guard);
}
void myWrapper1() {
std::lock_guard<std::mutex> guard(my_lock);
...do something else that requires my_lock to be locked...
myFunc(guard);
}
void myWrapper2() {
...
myFunc();
}