c++ - 与普通互斥锁相比,唯一锁如何工作?

标签 c++ c++11 visual-c++

我遇到了 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_locklock_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/

相关文章:

c++ - 如何将 TBB task_arena 类与 enqueue 和 wait_until_empty 一起使用

c++ - 为什么构造函数调用异常后没有释放unique_ptr?

c++ - 如何在 VC++ 中使用多核计算进行循环?

c - 将显示正在运行的进程的 Windows API

c++ - 当模板类未专门化时,成员函数专用模板的解决方法

c++ - memcpy 或 memmove 会导致复制类出现问题吗?

c++ - 单元测试、模拟和 unique_ptr

c++ - 使用 g++ 和 clang++ 对 condition_variable 进行虚假唤醒

c++ - wchar_t for Linux 和 for Windows 的区别和转换

c++ - 为什么我的模板参数包不起作用?