c++ - shared_ptr 和线程问题

标签 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 个线程使用 GetSharedObject 访问 SharedObject 并对其执行一些操作。

然而,在给它一些时间之后 - shared_ptruse_count() 将下降到 2 以下(它不应该)并最终低于 1 所以 object(objectA) 将被销毁。

编辑 显然这段代码中没有同步。但是我不明白这与 use_count() 低于 2 的事实有什么关系。为了引用计数,shared_ptr 保证是线程安全的,不是吗?

最佳答案

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

您还需要在某个时刻join()您的线程。

关于c++ - shared_ptr 和线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41877703/

相关文章:

c++ - 何时在抽象类 cpp 中声明 protected 字段

c++ - 在一维容器上使用 STL 算法函数

java - 抛出 Swing 异常时显示对话框

c++ - shared_ptr.reset() 不删除

带有宏的类中的 C++ 自动 shared_ptr 类型

c++ - 链接期间未定义的函数引用

c++ - 在 C++ 中递增 - 帮助理解示例程序输出

c# - 如何使用后台 worker 将参数(字符串)发送到 UI 线程?

c# - BackGround Thread with timer for application level-WPF Application

c++ - 如何在 C++11 lambda 中跟踪对象生命周期?