简体   繁体   English

shared_ptr和线程问题

[英]shared_ptr and threads issue

The code I'm currently working on had it's own RefPtr implementation which was failing at random. 我当前正在处理的代码具有自己的RefPtr实现,该实现随机失败。

I suspect that this could be a classic data race. 我怀疑这可能是经典的数据竞赛。 RefPtr has a pointer to original object that inherits from the RefCounted class. RefPtr具有指向从RefCounted类继承的原始对象的指针。 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. 此类包含一个非原子的引用计数器( m_refCount ),并且应用程序在通过RefPtr东西访问对象的某些RefPtr内崩溃。 Just like the object under RefPtr got destroyed. 就像RefPtr下的对象被破坏一样。 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) 由持有的对象实例RefPtr也由另外两个对象认为, 修改它(或内容),我100%肯定,他们有共同的它的所有权(这样m_refCount应该永远不会低于2)

I did try to replace the pointer with std::shared_ptr , but the crash is still there. 我确实尝试用std::shared_ptr替换指针,但是崩溃仍然存在。

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. 发生的事情是,多达4个线程使用GetSharedObject访问SharedObject并对其进行处理。

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. 但是,在给了一些时间之后, shared_ptruse_count()会降至2以下(不应),最终降至1以下,因此object(objectA)将被破坏。

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? 但是我看不出这与use_count()低于2的事实有何关系。shared_ptr出于引用计数的目的保证是线程安全的,不是吗?

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. shared_ptr在访问指向对象时不进行任何同步,它只是确保在指向该对象的所有引用被销毁后释放该对象。

You also need to join() your threads at some point. 您还需要在某个时候join()线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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