shared_ptr和threads问题

时间:2017-01-26 16:02:04

标签: c++ multithreading shared-ptr

我目前正在处理的代码有自己的RefPtr实现,它随机失败。

我怀疑这可能是一场经典的数据竞赛。 RefPtr有一个指向原始对象的指针,该对象继承自RefCounted类。此类包含一个非原子的引用计数器(m_refCount),并且应用程序通过RefPtr内容在某些线程访问对象中崩溃。就像RefPtr下的对象被摧毁一样。非常不可能。

RefPtr持有的对象实例也由另外两个修改它(或其内容)的对象持有,我100%确定他们已共享它的所有权(因此m_refCount永远不会低于2)

我确实尝试用std::shared_ptr替换指针,但崩溃仍然存在。

代表此问题的已提炼代码:

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

正在发生的事情是最多4个线程使用SharedObject访问GetSharedObject并对其执行操作。

但是,在给它一些时间之后 - use_count()的{​​{1}}将低于2(它不应该)并最终低于1,因此shared_ptr将被销毁。

修改 显然,此代码中没有同步。但是我没有看到这可能与use_count()低于2的事实有关。为了引用计数,shared_ptr保证是线程安全的,不是吗?

1 个答案:

答案 0 :(得分:1)

您在访问共享对象时没有任何同步。 shared_ptr在访问指向对象时不进行任何同步,它只是确保指向的内存在对它的所有引用都被销毁后被释放。

您还需要join()线程。