Fir*_*cer 6 c++ multithreading reference-counting
目前我已经使用以下方法获得了一些引用计数类:
class RefCounted
{
public:
void IncRef()
{
++refCnt;
}
void DecRef()
{
if(!--refCnt)delete this;
}
protected:
RefCounted():refCnt(0){}
private:
unsigned refCnt;
//not implemented
RefCounted(RefCounted&);
RefCounted& operator = (RefCounted&};
};
Run Code Online (Sandbox Code Playgroud)
我还有一个处理引用计数的智能指针类,虽然它没有统一使用(例如,在一两位性能关键代码中,我最小化了IncRef和DecRef调用的数量).
template<class T>class RefCountedPtr
{
public:
RefCountedPtr(T *p)
:p(p)
{
if(p)p->IncRef();
}
~RefCountedPtr()
{
if(p)p->DecRef();
}
RefCountedPtr<T>& operator = (T *newP)
{
if(newP)newP->IncRef();
if(p) p ->DecRef();
p = newP;
return *this;
}
RefCountedPtr<T>& operator = (RefCountedPtr<T> &newP)
{
if(newP.p)newP.p->IncRef();
if(p) p ->DecRef();
p = newP.p;
return *this;
}
T& operator *()
{
return *p;
}
T* operator ->()
{
return p;
}
//comparison operators etc and some const versions of the above...
private:
T *p;
};
Run Code Online (Sandbox Code Playgroud)
对于类本身的一般用途,我打算使用读写器锁定系统,但是我真的不想为每一个IncRef和DecRef调用获取一个写入器锁.
我还想到了在IncRef调用之前指针可能无效的情况,请考虑:
class Texture : public RefCounted
{
public:
//...various operations...
private:
Texture(const std::string &file)
{
//...load texture from file...
TexPool.insert(this);
}
virtual ~Texture()
{
TexPool.erase(this);
}
freind CreateTextureFromFile;
};
Texture *CreateTexture(const std::string &file)
{
TexPoolIterator i = TexPool.find(file);
if(i != TexPool.end())return *i;
else return new Texture(file);
}
Run Code Online (Sandbox Code Playgroud)
ThreadA ThreadB
t = CreateTexture("ball.png");
t->IncRef();
...use t... t2 = CreateTexture("ball.png");//returns *t
... thread suspended...
t->DecRef();//deletes t ...
... t2->IncRef();//ERROR
所以我想我需要完全改变引用计数模型,我在设计中返回后添加引用的原因是为了支持以下内容:
MyObj->GetSomething()->GetSomethingElse()->DoSomething();
Run Code Online (Sandbox Code Playgroud)
而不是必须:
SomeObject a = MyObj->GetSomething();
AnotherObject *b = a->GetSomethingElse();
b->DoSomething();
b->DecRef();
a->DecRef();
Run Code Online (Sandbox Code Playgroud)
在多线程环境中,c ++中有快速引用计数的简洁方法吗?
Edo*_* A. 16
使引用计数为原子,您将不需要任何锁定.在Windows :: InterlockedIncrement和:: InterlockedDecrement可以使用.在C++ 0x中,你有原子<>.
Mat*_*ice 10
除非你知道这是我刚才使用的特定瓶颈 boost::shared_ptr
它非常快,但是在分配额外控制块时会有一些额外的开销.另一方面,它有许多好处:
boost,如果你不是你应该另请注意,您可能不希望读取器/写入器锁定参考计数对象.争用很少,额外的开销将完全压倒你所拥有的任何好处.共享指针使用芯片级原子int操作实现,这明显优于普通互斥锁,后者明显快于读取器/写入器锁定.
如果您不想使用boost或C++ 0X,但仍需要无锁引用计数,则可以通过在代码中包含正确的特定于平台的原子增量/原子减量程序集例程来实现.举个例子,这是我用于引用计数的AtomicCounter类; 它适用于最常见的操作系统:
https://public.msli.com/lcs/muscle/html/AtomicCounter_8h_source.html
是的,这是一个令人讨厌的#ifdefs混乱.但它确实有效.