преобразование необработанного указателя в разделяемый указатель. Являются ли разделяемые указатели потокобезопасными? - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть следующий установщик и получатель, который дает мне необработанные указатели. К ним также можно получить доступ из разных потоков. Я хочу сделать 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));
}

При доступе к геттеру в другом классе он также должен увеличить счетчик ссылок, для общего указателя, я думаю, мне просто нужно присвоить его локальному общему указателю rit? Будет ли он автоматически увеличивать счетчик ссылок?

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

доступ из другого места

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

Обе функции могут быть доступны из разных потоков - возможно, в других местах вызывается метод получения, и прежде чем я добавлю метод определения, вызванный из другого потока и выпустивший его, так же был и CS для. В данном случае это так нужен? Модифицированный в порядке?

1 Ответ

0 голосов
/ 06 сентября 2018

Согласно cppreference :

Все функции-члены (включая конструктор копирования и назначение копирования) могут вызываться несколькими потоками в разных экземплярах shared_ptr без дополнительной синхронизации, даже если эти экземпляры являются копиями и имеют общее владение одним и тем же объектом. Если несколько потоков выполнения обращаются к одному и тому же shared_ptr без синхронизации и любой из этих обращений использует неконстантную функцию-член shared_ptr, тогда произойдет гонка данных; перегрузки shared_ptr элементарных функций могут использоваться для предотвращения гонки данных.

Так что, если вы используете const методы shared_ptr, вы в безопасности. Но в вашем случае вы пишете одновременно (CopyConstructor в getter и reset в setter) в один и тот же экземпляр std::shared_ptr (а именно, переменную-член m_pObj), и это приводит к неопределенному поведению.

Кроме того, использование методов базового объекта различными потоками (например, вашим IMyInterface::Release -методом) также приводит к гонкам данных.

И поэтому вам потребуется CS для синхронизации.

...