【问题标题】:Is std::mutex as a member variable thread-safe for multiple threads?std::mutex 作为成员变量对于多线程来说是线程安全的吗?
【发布时间】:2018-12-24 15:39:59
【问题描述】:

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

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

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

我很好奇可以使用这样的互斥锁吗?

有很多示例代码使用了一种用于互斥锁的包装类,例如保护或其他东西。

我更喜欢简单地使用它并且想要明确地解锁。不在破坏时间。

#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();
}

【问题讨论】:

  • 是的,没关系。本身容易受到数据竞争影响的mutex 将毫无用处。有趣的是,您认为手动解锁互斥锁比使用 lock_guard简单
  • 这仅在两个线程访问A 的同一实例时才有效。从描述中看不清楚
  • 对不起,是同一个实例。
  • @Praetorian “数据竞争”的定义意味着一个普通的变量,而不是一个同步原语。

标签: c++ multithreading thread-safety mutex


【解决方案1】:

它基本上可以工作,但是你需要注意几个“陷阱”:

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

  2. 1234563 (避免这种情况的典型方法是确保所有线程在它们所依赖的互斥体被破坏之前已经join()'d - 或者通过将互斥体移出对象并进入更高您可以保证在线程仍在运行时不会被破坏的级别对象)

【讨论】:

  • 谢谢。很有帮助。
  • #2 可以通过像 std::shared_ptr 这样的智能指针来阻止。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-19
  • 1970-01-01
  • 2014-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-01
相关资源
最近更新 更多