gpt4 book ai didi

c++ - 引用计数类和多线程

转载 作者:搜寻专家 更新时间:2023-10-31 00:36:44 25 4
gpt4 key购买 nike

我是多线程编程的新手,对此我仍然感到困惑。

下面是我的引用计数类:

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) 不是?我上面的例子错了吗?

提前感谢您的意见和建议,使我的类(class)完全线程安全。

最佳答案

你的分析不对;您发布的代码正确使用了 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 方法。因此共享对象会自动计算事件“引用对象”的数量。

关于c++ - 引用计数类和多线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21119061/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com