shared_ptr和线程问题

shared_ptr and threads issue

本文关键字:线程 问题 ptr shared      更新时间:2023-10-16

我目前正在处理的代码有自己的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的事实有什么关系。为了引用计数,sharedptr被保证是线程安全的,不是吗?

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

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