当前位置:  开发笔记 > 编程语言 > 正文

C++:多线程和refcounted对象

如何解决《C++:多线程和refcounted对象》经验,为你挑选了0个好方法。

我目前正在尝试将单线程程序传递给多线程.该软件大量使用"refCounted"对象,这导致多线程中的一些问题.我正在寻找一些可能解决我的问题的设计模式.

主要问题是线程之间的对象删除,通常删除只减少引用计数,当refcount等于零时,则删除对象.这在monothread程序中运行良好,并且可以通过大对象的副本实现一些很好的性能提升.

但是,在多线程中,两个线程可能希望同时删除同一个对象,因为该对象受互斥锁保护,只有一个线程删除该对象并阻塞另一个.但是当它释放互斥锁时,另一个线程继续执行无效(释放对象),这会导致内存损坏.

以下是此类RefCountedObject的示例

class RefCountedObject
{
public:
RefCountedObject()
:   _refCount( new U32(1) )
{}

RefCountedObject( const RefCountedObject& obj )
:   _refCount( obj._refCount )
{
    ACE_Guard< ACE_Mutex > guard( _refCountMutex );
    ++(*_refCount);
}

~RefCountedObject()
{
    Destroy();
}

RefCountedObject& operator=( const RefCountedObject& obj )
{
    if( this != &obj )
    {
        Destroy();
        ACE_Guard< ACE_Mutex > guard( _refCountMutex );
        _refCount = obj._refCount;
        ++(*_refCount);
    }

    return *this;
}

private:
    void Destroy()
    {
        ACE_Guard< ACE_Mutex > guard( _refCountMutex );  // thread2 are waiting here
        --(*_refCount);         // This cause a free memory write by the thread2
        if( 0 == *_refCount )
            delete _refCount;
    }

private:
    mutable U32* _refCount;
    mutable ACE_Mutex _refCountMutex; // BAD: this mutex only protect the refCount pointer, not the refCount itself
};

假设两个线程想要删除相同的RefCountedObject,两者都在~RefCountedObject中并调用Destroy(),第一个线程锁定了互斥锁,另一个线程正在等待.在第一个线程删除对象之后,第二个线程将继续执行并导致空闲内存写入.

任何人都有类似问题的经验,并找到了解决方案?


感谢大家的帮助,我意识到自己的错误:互斥锁只是保护refCount指针,而不是refCount本身!我创建了一个受互斥保护的RefCount类.现在,所有refCounted对象之间共享互斥锁.

现在一切正常.

推荐阅读
N个小灰流_701
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有