std::shared_ptr 的线程安全

Thread safety with std::shared_ptr

我正在阅读有关 std::shared_ptr 的线程安全及其提供的原子操作重载的信息,并且想知道它在 class.

中的特定用例

根据我对 shared_ptr 承诺的线程安全的理解,像这样的 get 方法是安全的:

class MyClass 
{
std::shared_ptr<int> _obj;
public:
    void start() 
    {
        std::lock_guard<std::mutex> lock(_mtx);
        _obj = std::make_shared<int>(1);
    }

    void stop()
    {
          std::lock_guard<std::mutex> lock(_mtx);
        _obj.reset();

    }
    std::shared_ptr<int> get_obj() const
    {
        return _obj; //Safe (?)
    }
};

getter 应该是安全的,因为对象将在任何线程的任何时候被初始化或为空。

但是如果我想在对象为空时抛出异常怎么办,我需要在 return 对其进行检查之前检查它,我现在是否必须在那里加锁(因为 stop() 可能是在 if 和 return 之间调用?或者是否可以使用共享指针的锁定机制而不使用此方法中的锁:

   std::shared_ptr<int> get_obj() const
    {
        auto tmp = _obj;
        if(!tmp) throw std::exception();
        return tmp;
    }

std::shared_ptr 个实例不是线程安全的。可以从多个线程修改全部指向同一对象的多个实例,但单个实例不是线程安全的。见 https://en.cppreference.com/w/cpp/memory/shared_ptr:

All member functions (including copy constructor and copy assignment) can be called by multiple threads on different instances of shared_ptr without additional synchronization even if these instances are copies and share ownership of the same object. If multiple threads of execution access the same shared_ptr without synchronization and any of those accesses uses a non-const member function of shared_ptr then a data race will occur; the shared_ptr overloads of atomic functions can be used to prevent the data race.

因此,您需要在 get_obj 方法中锁定互斥锁,或者在 startstop 方法中使用 std::atomic_loadstd::atomic_store