简体   繁体   中英

shared_ptr and threads issue

The code I'm currently working on had it's own RefPtr implementation which was failing at random.

I suspect that this could be a classic data race. RefPtr has a pointer to original object that inherits from the RefCounted class. This class contains a reference counter ( m_refCount ) that is not atomic and an application was crashing inside some threadwork accessing object through RefPtr stuff. Just like the object under RefPtr got destroyed. Quite impossible.

The object instance that is held by RefPtr is also held by two other objects that do not modify it (or its contents) and I'm 100% sure that they have shared ownership of it (so m_refCount should never go below 2)

I did try to replace the pointer with std::shared_ptr , but the crash is still there.

The distilled code representing this issue:

class SharedObjectA
{
    public:
        int a;
}

class Owner
{
    public:
        shared_ptr<SharedObjectA> objectA;
}

class SecondOwner
{
    shared_ptr<SharedObjectA> objcectA;
    public:
        shared_ptr<SharedObjectA> GetSharedObject() { return objectA;}
        void SetSharedObject(shared_ptr<SharedObjectA>  objA) { objectA = objA;}
}

void doSomethingThatTakesTime(SecondOwnerA* owner)
{
    sleep(1000+rand()%1000);
        shared_ptr<SharedObjectA> anObject = owner->GetSharedObject();
        int value = anObject.a;
        std::cout << " says: " << value;
}

int main()
{
    Owner ownerA;
    ownerA.objectA.reset(new SharedObjectA());

    SecondOwner secondOwner;
    secondOwner.SetSharedObject(ownerA.objectA);

    //objectA instance

    while(true)
    {
        for(int i=0;i<4;i++)
        {
            std::thread tr(doSomethingThatTakesTime,secondOwner);
        }

        sleep(4*1000);
    }
}

What's happening is up to 4 threads access SharedObject using GetSharedObject and do something with it.

However, after giving it some time - the use_count() of shared_ptr will go down below 2 (it should not) and eventually below 1 so the object(objectA) will get destroyed.

Edit Obviously there is no synchronization in this code. However i don't see how this could be related to the fact the use_count() getting below 2. the shared_ptr is guaranteed to be thread safe for the sake of reference counting, isn't it?

You don't have any kind of synchronization on access to the shared object. shared_ptr does not do any synchronization in access to the pointed-to object, it just ensures that the memory pointed to gets released after all references to it are destroyed.

You also need to join() your threads at some point.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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