我目前正在处理的代码有它自己的 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_ptr
的 use_count()
将下降到 2 以下(它不应该)并最终低于 1 所以 object(objectA)
将被销毁。
编辑 显然这段代码中没有同步。但是我不明白这与 use_count() 低于 2 的事实有什么关系。为了引用计数,shared_ptr 保证是线程安全的,不是吗?
最佳答案
您在访问共享对象时没有任何类型的同步。 shared_ptr
在访问指向的对象时不做任何同步,它只是确保在销毁所有指向它的引用后释放指向的内存。
您还需要在某个时刻join()
您的线程。
关于c++ - shared_ptr 和线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41877703/