我目前正在尝试将单线程程序传递给多线程.该软件大量使用"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对象之间共享互斥锁.
现在一切正常.