在多线程编程中,我们经常用到InterlockedDecrement , 此处有个细节问题,简单聊一下.
下面的程序用mReferenceCount来控制是否要删除自己.
void AddRef()
{}
猛的一看,好像没什么问题, 大家看Release这个函数, InterlockedDecrement是个原子操作,假设当两个线程到到达这个函数时,
mReferenceCount为2, 只有一个线程要执行InterlockedDecrement操作, 那么mReferenceCount减一为 1, 这个线程继续往下
执行,当正在比较操作时, 第二个线程也执行了InterlockedDecrement操作,那么mReferenceCount再减一为0. 好了问题出现了.
第一个线程在比较操作时, 发现mRerenceCount为0,就去执行delete操作. 当第二个线程到达比较操作时, 发现mReferenceCount
也为0, 也去执行delete操作,连续两次delete, 程序就崩溃了.
这个问题很难发现,所以写了博克, 给诸位同行提个醒.
下面是解决方案:
void Release()
{
long refCount = InterlockedDecrement(&mReferenceCount);
if (0 == refCount)
{
delete this;
}
}
我们加入了refCount局部变量,也就是说每个线程在Release函数中各自维护一个计数结果, 这样就避免了重复删除.