在多線程編程中,我們經常用到InterlockedDecrement , 此處有個細節問題,簡單聊一下.
下面的程序用mReferenceCount來控制是否要刪除自己.
void AddRef()
{InterlockedIncrement(&mReferenceCount);
}
void Release()
{
InterlockedDecrement(&mReferenceCount);
if (0 == mReferenceCount)
{
delete this;
}
}
猛的一看,好像沒什麼問題, 大家看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函數中各自維護一個計數結果, 這樣就避免了重複刪除.