【发布时间】:2014-01-14 16:47:29
【问题描述】:
我是多线程编程的新手,我仍然对此感到困惑。
下面是我的引用计数类:
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)) 部分是原子的,但 if (InterlockedDecrement(&mRefCount)==0) 不是? 我上面的例子错了吗?
提前感谢您的意见和建议,以使我的课程完全线程安全。
【问题讨论】:
-
您正在删除一个非动态成员变量 (
delete[] m_pnData),并且没有为保护实例可以自毁的类的构造提供任何启示(即具有私有的静态类工厂方法)构造函数家族)。也就是说,我认为您的崩溃可能与引用计数无关。坦率地说,delete操作数上的固定转换应该同样令人担忧。我认为您没有为此使用std::shared_ptr<Rbuffer>是有原因的,因为这会使 all 这一切变得无关紧要。
标签: c++ multithreading reference-counting