将原始指针转换为共享指针。共享指针线程安全吗?

时间:2018-09-06 06:42:07

标签: c++11 shared-ptr

我有以下的setter和getter,它给了我原始的指针。 这些也可以从不同的线程访问。我想使m_pObj成为共享指针--std :: shared_ptr <(IMyInterface> m_pObj;

代码就是这样。 如果m_obj不为null,则必须释放并在SetPointer中分配新指针

void MyClass::SetPointer(IMyInterface* pObj)
{
    EnterCriticalSection(&cs1)
    if (NULL != m_pObj)//Member variable to hold the incoming pointer
    {
        m_pObj>Release();
        m_pObj= NULL;
    }

    m_pObj= pObj;

    if (NULL != m_pObj )
    {
        m_pObj->AddRef();
    }
    LeaveCriticalSection(&cs1)
}

IMyInterface* MyClass::GetPointer()
{ 
    EnterCriticalSection(&cs1)
    if (NULL != m_pObj)
    {
        m_pObj->AddRef();
    }
    LeaveCriticalSection(&cs1)
    return m_pObj;
}

void MyClass::SetPointer(IMyInterface* pObj)
{
    if (NULL != m_pObj)
    {
        m_pObj->Release();
        m_pObj= NULL;
    }
    m_pObj = std::shared_ptr<IMyInterface>(pObj));
}

在另一个类中访问getter时,它也应该增加引用计数,对于共享指针,我认为我只需要将其分配给本地共享指针rit?会自动增加引用计数吗?

std::shared_ptr<IMyInterface> MyClass::GetPointer()
{
    return m_pObj;
};

从其他地方访问

std::shared_ptr<IMyInterface> pObj1 = GetPointer();//hope it would increase th reference count

这两个函数都可以从不同的线程访问-可能在其他地方调用了getter,在我添加ref之前,从不同的线程调用了setter并释放了它,因此CS也是如此。需要吗?修改后的一个可以吗?

1 个答案:

答案 0 :(得分:0)

根据cppreference

  

所有成员函数(包括副本构造函数和副本分配)可以由shared_ptr的不同实例上的多个线程调用,而无需额外同步,即使这些实例是副本并共享同一对象的所有权。如果多个执行线程在不同步的情况下访问同一个shared_ptr,并且这些访问中的任何一个都使用了shared_ptr的非常量成员函数,则将发生数据争用;否则,将导致数据争用。原子函数的shared_ptr重载可用于防止数据争用。

因此,如果您使用x.patchValue({ unit_price: selectedIngredient.price }); x.get('unit_price').markAsTouched(); 的{​​{1}}方法,那是安全的。但是在您的情况下,您会同时(在getter中的CopyConstructor和setter中的const)同时写入shared_ptr的同一实例(即成员变量reset),这将导致不确定的行为。

此外,通过不同的线程(例如,您的std::shared_ptr方法)使用基础对象的方法也会导致数据争用。

因此您将需要CS进行同步。