我目前正在处理的代码有自己的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保证是线程安全的,不是吗?
答案 0 :(得分:1)
您在访问共享对象时没有任何同步。 shared_ptr
在访问指向对象时不进行任何同步,它只是确保指向的内存在对它的所有引用都被销毁后被释放。
您还需要join()
线程。