简体   繁体   English

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

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

Is std::mutex as a member variable thread-safe for multiple threads? std :: mutex作为成员变量对多个线程是线程安全的吗?

There is an instance of a class has a variable and mutex as a member. 有一个类的实例,该实例具有变量和互斥体作为成员。

Each function is called in different threads. 每个函数在不同的线程中调用。

I am curious that is it okay to use a mutex like this? 我很好奇可以使用这样的互斥锁吗?

There are lots of example codes using a kind of wrapper class for mutex like guard or something. 有很多示例代码使用一种针对互斥量的包装类,例如Guard或类似的东西。

I prefer to use it simply and want to unlock explicitly. 我更喜欢简单地使用它,并希望显式解锁。 Not in destructing time. 没有破坏时间。

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

It will basically work, but there are a couple of "gotchas" you'll want to watch out for: 它基本上可以正常工作,但是您需要注意几个“陷阱”:

  1. If the code in between the lock() and unlock() calls ever throws an exception (or uses the return or goto keywords), the unlock() call might never be reached, and thus your mutex will remain locked indefinitely. 如果在lock()unlock()调用之间的代码抛出异常(或使用returngoto关键字),则可能永远不会到达unlock()调用,因此您的互斥锁将无限期保持锁定状态。 This will probably result in the deadlocking of your application, as every subsequent thread that tries to the lock the mutex will end up waiting forever for their own lock() call to return. 这可能会导致应用程序死锁,因为每个随后尝试锁定互斥锁的线程最终都将永远等待自己的lock()调用返回。 (This hazard goes away if you use a lock_guard/ RAII approach instead, which is why that is the recommended/safer way to do it) (如果改为使用lock_guard / RAII方法,则此危险消失了,这就是为什么这样做是推荐的/更安全的方法)

  2. If the A object gets deleted while it is still accessible to other threads, it will likely result in undefined behavior, since the member-variable-mutex the threads depend on for serialization will have been destroyed. 如果A对象在仍可被其他线程访问的同时被删除,则可能会导致不确定的行为,因为线程所依赖的member-variable-mutex序列化将被销毁。 (The typical way to avoid this is to make sure all threads have been join() 'd before the mutexes they depend on are destructed -- or by moving the mutexes out of the object and into some higher-level object that you can guarantee won't get destroyed while the threads are still running) (避免这种情况的典型方法是,在销毁它们所依赖的互斥对象之前 ,确保所有线程都已经被join() '了-或通过将互斥对象移出对象并移入可以保证的更高级别的对象中在线程仍在运行时不会被破坏)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM