c-引用计数类和多线程
作者:互联网
我是多线程编程的新手,对此我仍然感到困惑.
以下是我的参考计数课程:
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
崩溃的原因可能只是(InterlockedDecrement(& mRefCount))部分是原子的,但是如果(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
特别是,以下简单代码会引起混乱.
{
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方法.因此,共享库会自动计算活动“参考对象”的数量.
标签:reference-counting,c,multithreading 来源: https://codeday.me/bug/20191011/1892281.html