与普通互斥锁相比,独特锁如何工作?

Lea*_*ozo 3 c++ visual-c++ c++11

我偶然发现了一本书提供的代码示例.顺便说一句这本书有不好的评论.我很遗憾我买了它

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();
}
Run Code Online (Sandbox Code Playgroud)

我不满意这本书对它是如何工作的解释以及我为什么要使用它.我已经知道互斥锁如何工作及其实现,但我很难理解上面代码的第二行.为什么它有一个可变的关键字?

我是C++编程的全新人物.因此,基本的解释水平对我有很大的帮助.

Jon*_*ely 8

这个例子看起来完全是愚蠢的.

第二行是声明一个非静态数据成员,和

  • 该成员是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();
}
Run Code Online (Sandbox Code Playgroud)

但是这个手动解锁具有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
Run Code Online (Sandbox Code Playgroud)

mutable关键字是必要的,这样可以锁定在互斥const成员函数.锁定和解锁互斥锁是一种非常量操作,它修改互斥锁,const如果成员不可变,则不允许在成员中使用互斥锁.