我遇到了 book 提供的这段代码示例.顺便说一句,这本书的评论很差。后悔买了它
std::mutex m_mutex;
mutable std::unique_lock<std::mutex> m_finishedQueryLock{ m_mutex, std::defer_lock };
bool m_playerQuit{ false };
void SetPlayerQuit()
{
m_finishedQueryLock.lock();
m_playerQuit = true;
m_finishedQueryLock.unlock();
}
我不满意本书对它的工作原理以及我为什么要使用它的解释。我已经对互斥锁的工作原理及其实现有所了解,但我很难理解上面代码的第二行。为什么它里面有一个可变关键字?
我对 C++ 编程完全陌生。所以基本水平的解释会对我有很大帮助。
最佳答案
这个例子看起来很愚蠢。
第二行声明了一个非静态数据成员,
- 成员是
mutable
(出于以下原因); - 成员是
std::unique_lock<std::mutex>
类型的对象,这是用于锁定/解锁关联的互斥对象的辅助类型; - 在创建类的实例时通过调用其构造函数并传递
m_mutex
来初始化成员和特殊标签std::defer_lock
作为论点。
但这样做是愚蠢的,如果这本书有这样的例子,我也不会感到惊讶。
点 unique_lock
就是锁定关联的互斥锁,然后在它超出范围时自动解锁。创建 unique_lock
像这样的成员是愚蠢的,因为它不会在函数末尾超出范围,所以代码绝对没有优势:
mutable std::mutex m_mutex;
bool m_playerQuit{ false };
void SetPlayerQuit()
{
m_mutex.lock();
m_playerQuit = true;
m_mutex.unlock();
}
但是这个手动解锁有所有的问题unique_lock
旨在解决问题,因此它应该使用作用域锁(unique_lock
或 lock_guard
)但仅在函数范围内,而不是作为成员:
mutable std::mutex m_mutex;
bool m_playerQuit{ false };
void SetPlayerQuit()
{
std::lock_guard<std::mutex> lock(m_mutex);
m_playerQuit = true;
} // m_mutex is automatically unlocked by the ~lock_guard destructor
mutable
关键字是必需的,以便您可以锁定 const
中的互斥体。成员函数。锁定和解锁互斥体是一种修改互斥体的非常量操作,这在 const
中是不允许的。成员,如果它不是可变的。
关于c++ - 与普通互斥锁相比,唯一锁如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32135380/