使用std :: shared_ptr进行线程安全 [英] Thread safety with std::shared_ptr

查看:149
本文介绍了使用std :: shared_ptr进行线程安全的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读std :: shared_ptr的线程安全性以及它提供的原子操作重载,并且想知道类中它的特定用例.

I was reading about thread safety of std::shared_ptr and about the atomic operations overloads it provides and was wondering regarding a specific use case of it in a class.

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

From my understanding of the thread safety that is promised from shared_ptr, it is safe to have a get method like so:

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

该吸气剂应该是安全的,因为该对象将在任何线程的任何位置被初始化或为空.

The getter should be safe since the object will either be initializes or empty at any point from any thread.

但是如果我想在对象为空的情况下引发异常该怎么办,我需要在返回它之前对其进行检查,我现在是否必须在其中放置一个锁(因为可能在if和return之间调用stop()))?或者可以使用共享指针的锁定机制而不在此方法中使用锁:

But what if I want to throw an exception if the object is empty, I need to check it before returning it, do I have to put a lock there now (since stop() might be called between the if and the return)? Or is it possible to use the locking mechanism of the shared pointer and not use a lock in this method:

   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:

std::shared_ptr instances are not thread safe. Multiple instances all pointing to the same object can be modified from multiple threads but a single instance is not thread safe. See https://en.cppreference.com/w/cpp/memory/shared_ptr:

所有成员函数(包括副本构造函数和副本分配)可以由shared_ptr的不同实例上的多个线程调用,而无需额外的同步,即使这些实例是副本并共享同一对象的所有权.如果多个执行线程在不同步的情况下访问同一个shared_ptr,并且这些访问中的任何一个都使用了shared_ptr的非常量成员函数,则将发生数据争用;否则,将导致数据争用.原子函数的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 方法中锁定互斥锁,或者在 start stop 方法

You therefore either need to lock your mutex in your get_obj method or use std::atomic_load and std::atomic_store in your start and stop methods

这篇关于使用std :: shared_ptr进行线程安全的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆