std::mutex作为一个成员变量对多个线程来说是安全的吗

Is std::mutex as a member variable thread-safe for multiple threads?

本文关键字:线程 安全 成员 mutex std 一个 变量      更新时间:2023-10-16

std::mutex作为成员变量对多个线程来说是安全的吗?

有一个类的实例有一个变量和互斥对象作为成员。

每个函数都在不同的线程中调用。

我很好奇,像这样使用互斥可以吗?

有很多示例代码使用一种包装类来实现类似于guard之类的互斥对象。

我更喜欢简单地使用它,并希望明确地解锁。不是在破坏时间。

#include <mutex>
#include <stdio.h>
class A {
private:
bool _is;
std::mutex _mutex;
}
// this function runs in Thread A
void A::read() {
_mutex.lock();
printf("%d", _is);
_mutex.unlock();
}
// this function runs in Thread B
void A::write() {
_mutex.lock();
printf("%d", _is);
_is = !_is;
_mutex.unlock();
}

它基本上会起作用,但有几个"问题"需要注意:

  1. 如果lock()unlock()调用之间的代码抛出异常(或使用returngoto关键字(,则可能永远无法访问unlock()调用,因此互斥锁将无限期保持锁定状态。这可能会导致应用程序死锁,因为每个试图锁定互斥对象的后续线程最终都将永远等待它们自己的lock()调用返回。(如果你使用lock_guard/RAII方法,这种危险就会消失,这就是为什么这是推荐/更安全的方法(

  2. 如果A对象在其他线程仍然可以访问的情况下被删除,则可能会导致未定义的行为,因为线程序列化所依赖的成员变量互斥将被破坏。(避免这种情况的典型方法是确保所有线程在它们所依赖的互斥对象被销毁之前都是join()'d,或者通过将互斥对象从对象中移动到某个更高级别的对象中,可以保证在线程仍在运行时不会被销毁(