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