我是多线程编程的新手,对此我仍然感到困惑。
下面是我的引用计数类:
class Rbuffer
{
private:
char *m_pnData;
volatile unsigned int mRefCount;
public:
Rbuffer(int nLength) : mRefCount(0)
{
m_pnData = new char[nLength];
}
~Rbuffer(){
delete[] m_pnData;
}
void decRef() {
if(InterlockedDecrement(&mRefCount)==0){
delete (Rbuffer *)this;
}
}
void incRef() {
InterlockedIncrement(&mRefCount);
}
};
它是完全线程安全的吗?可以排除这种情况吗:
ThreadA ThreadB
PointerToRBuffer->incRef();//mRefCount 1
switch->
PointerToRBuffer->incRef();//mRefCount 2
<-switch
PointerToRBuffer->decRef();
InterlockedDecrement(&mRefCount)//mRefCount 1
switch->
PointerToRBuffer->decRef();//mRefCount 0!
InterlockedDecrement(&mRefCount);
if (0==0)
delete (Rbuffer *)this;
<-switch
if (0==0)
//deleting object, that doesn't exist
delete (Rbuffer *)this;
//CRASH
崩溃的原因可能只是(互锁减量(&mRefCount))部分是原子的,但是if (InterlockedDecrement(&mRefCount)==0)不是?
我上面的例子有错吗?
预先感谢您的意见和建议,使我的课程完全线程安全。
你的分析不对;您发布的代码正在使用interlockedDecrement
正确。
这是安全使用
if(InterlockedDecrement(&mRefCount)==0)
cleanup();
..但这确实会出现你所描述的问题
InterlockedDecrement(&mRefCount);
if (mRefCount==0)
cleanup();
然而,使用delete this
更有可能是问题的原因。您不太可能通过此处描述的“绝对 100% 确定”测试:http://www.parashift.com/c++-faq-lite/delete-this.html http://www.parashift.com/c++-faq-lite/delete-this.html
特别是下面的简单代码会造成混乱。
{
RBuffer x; // count is what... ? zero
x.incRef(); // make count one
x.decRef(); // make count zero, and deletes itself
} // now x goes out of scope, so destructor is called a second time = chaos!
正常的“引用计数”习惯用法涉及“共享对象”(带有计数)和引用共享对象的简单“引用对象”(不是 C++ 引用,尽管语义相似)。 “引用对象”的构造函数和析构函数负责调用incref/decref
共享对象上的方法。因此共享对象会自动计算活动“引用对象”的数量。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)