c++ - 在 C++ 中像这样自动化互斥安全吗?

标签 c++ multithreading thread-safety mutex

我现在正在学习互斥体和线程。我想知道使用这样的类自动执行互斥是否有任何危险或本质上的错误:

class AutoMutex
{
private:
    std::mutex& m_Mutex;

public:
    AutoMutex(std::mutex& m) : m_Mutex(m)
    {
        m_Mutex.lock();
    }
    ~AutoMutex()
    {
        m_Mutex.unlock();
    }
};

然后,当然,您可以像这样使用它:

void SomeThreadedFunc()
{
    AutoMutex m(Mutex); // With 'Mutex' being some global mutex.
    // Do stuff
}

这个想法是,在构造 AutoMutex 对象时,它会锁定互斥体。然后,当它超出范围时,析构函数会自动将其解锁。

如果整个函数不需要它,您甚至可以将其放入作用域中。像这样:

void SomeFunc()
{
    // Do stuff
    {
        AutoMutex m(Mutex);
        // Do race condition stuff.
    }
    // Do other stuff
}

这样可以吗?我个人不认为它有什么问题,但由于我不是最有经验的,我觉得我可能缺少一些东西。

最佳答案

使用 RAII 包装器是安全的,实际上比直接使用互斥成员函数更安全,但也没有必要编写,因为标准库已经提供了这一点。它称为std::lock_guard

但是,您的实现并不完全安全,因为它是可复制的,并且拷贝将尝试重新解锁互斥体,这将导致未定义的行为。 std::lock_guard 通过不可复制解决了这个问题。

还有 std::unique_lock ,它非常相似,但允许在生命周期内释放锁等操作。如果需要锁定多个互斥锁,则应使用 std::scoped_lock。使用多个锁防护可能会导致死锁。 std::scoped_lock 也可以与单个互斥体一起使用,因此您可以用它替换锁防护的所有使用。

关于c++ - 在 C++ 中像这样自动化互斥安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73762161/

相关文章:

java - 异步数据库库是如何实现的?

c# - 在另一个线程中调用函数是否安全?

c++ - Google 服务器正在响应一个过时的 html 文件

vb.net - 尽管使用了调用,但 UI 线程没有通过线程更新刷新

java - 只允许两个线程操作一个函数

c# - 调用 Task.Result 时出现 ThreadAbortException

python - python 的 "in"语言构造对于列表是线程安全的吗?

c++ - Internet Explorer BHO,写入注册表和管理员权限

java - 使用 MinGW C++ 编译 64 位静态库以用于 Java (JNI)

c++ - 银行模拟无限循环