InterlockedDecrement用法注意的事项

在多线程编程中,我们经常用到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函数中各自维护一个计数结果, 这样就避免了重复删除.

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Creating Windows CreateMDIWindow CreateWindow CreateWindowEx RegisterClass RegisterClassEx UnregisterClass Message Processing BroadcastSystemMessage CallNextHookEx CallWindowProc DefFrameProc DefMDIChildProc DefWindowProc DispatchMessage GetMessage GetMessageExtraInfo GetMessagePos GetMessageTime GetQueueStatus InSendMessage PeekMessage PostMessage PostQuitMessage PostThreadMessage RegisterWindowMessage ReplyMessage SendMessage SendMessageCallback SendMessageTimeout SendNotifyMessage SetMessageExtraInfo SetWindowsHookEx TranslateMessage UnhookWindowsHookEx WaitMessage Window Information AnyPopup ChildWindowFromPoint ChildWindowFromPointEx EnableWindow EnumChildWindows EnumPropsEx EnumThreadWindows EnumWindows FindWindow FindWindowEx GetClassInfoEx GetClassLong GetClassName GetClientRect GetDesktopWindow GetFocus GetForegroundWindow GetNextWindow GetParent GetProp GetTopWindow GetWindow GetWindowLong GetWindowRect GetWindowText GetWindowTextLength IsChild IsIconic IsWindow IsWindowEnabled IsWindowUnicode IsWindowVisible IsZoomed RemoveProp SetActiveWindow SetClassLong SetFocus SetForegroundWindow SetParent SetProp SetWindowLong SetWindowText WindowFromPoint Processes and Threads CreateEvent CreateMutex CreateProcess CreateSemaphore CreateThread DeleteCriticalSection DuplicateHandle EnterCriticalSection ExitProcess ExitThread GetCurrentProcess GetCurrentProcessId GetCurrentThread GetCurrentThreadId GetExitCodeProcess GetExitCodeThread GetPriorityClass GetThreadPriority GetWindowThreadProcessId InitializeCriticalSection InterlockedDecrement InterlockedExchange InterlockedIncrement LeaveCriticalSection OpenEvent OpenMutex OpenProcess OpenSemaphore PulseEvent ReleaseMutex ReleaseSemaphore ResetEvent ResumeThread SetEvent SetPr
Interlocked是一组Windows API,提供了一些原子操作,可以保证在执行时不会被其他线程中断,从而确保了线程安全。它通常用于保护共享资源,防止并发访问时出现竞争条件。 以下是Interlocked的一些常用函数: 1. InterlockedIncrement:原子地将指定变量的值加一。 ```C++ LONG InterlockedIncrement(LONG volatile *lpAddend); ``` 2. InterlockedDecrement:原子地将指定变量的值减一。 ```C++ LONG InterlockedDecrement(LONG volatile *lpAddend); ``` 3. InterlockedExchange:原子地将指定变量的值设置为一个新值,并返回旧值。 ```C++ LONG InterlockedExchange(LONG volatile *Target, LONG Value); ``` 4. InterlockedCompareExchange:原子地比较指定变量的值和期望值,并在它们相等时将变量的值设置为一个新值,返回旧值。 ```C++ LONG InterlockedCompareExchange(LONG volatile *Destination, LONG Exchange, LONG Comparand); ``` 使用Interlocked的一般步骤如下: 1. 定义一个变量,用于存储共享资源的值。 ```C++ LONG g_sharedVariable = 0; ``` 2. 在访问共享资源的地方使用Interlocked函数。 ```C++ InterlockedIncrement(&g_sharedVariable); ``` 以上代码实现了对共享变量g_sharedVariable的原子增量操作。 需要注意的是,Interlocked函数使用时需要将变量的指针传入函数中,而且变量必须是volatile类型的,以确保编译器不会对变量进行优化,从而造成不必要的错误。 另外,Interlocked函数的执行是原子性的,不会被其他线程中断,因此可以保证线程安全。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值