InterlockedIncrement vs EnterCriticalSection / counter ++ / LeaveCriticalSection [英] InterlockedIncrement vs EnterCriticalSection/counter++/LeaveCriticalSection

查看:223
本文介绍了InterlockedIncrement vs EnterCriticalSection / counter ++ / LeaveCriticalSection的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些多线程代码(请参阅 Windows API线程池简单示例)为我使用计数器来标识线程。

I have some multithreaded code (see question Windows API Thread Pool simple example ) for which I am using a counter to identify a thread.

我建议使用一个InterlockedIncrement在线程的回调函数中增加这个计数器。但是这似乎没有正确地锁定变量,因为我遇到一些并发问题。我通过手动使用关键部分替换了InterlockedIncrement:EnterCriticalSection / counter ++ / LeaveCriticalSection现在可以很好地工作。

I have been advised to use an InterlockedIncrement to increment this counter in the thread's callback function. However this didn't seem to properly lock the variable, as I encountered some concurrency issues. I replaced the InterlockedIncrement by using a critical section manually : EnterCriticalSection/counter++/LeaveCriticalSection and this now works perfectly.

为什么会这样?不是两个选项应该严格相等?
注意,我说的只是一对(约10)个线程。

Why is it so ? Aren't the two options supposed to be strictly equivalent ? Note that I am talking about launching just a couple (about 10) of threads.

推荐答案

正确使用 InterlockedIncrement

Your code is not using InterlockedIncrement correctly.

InterlockedIncrement(&(thread.threadCount)); 
DWORD tid = (thread.threadCount-1)%thread.size(); 

这会执行的原子增量thread.threadCount ,但是不是保存atomically-incremented值,而是忽略它,并返回到 thread.threadCount 变量(在此期间可能已被另一个线程递增) 。

This performs an atomic increment of thread.threadCount, but instead of saving the atomically-incremented value, you ignore it and go back to the thread.threadCount variable (which may have been incremented by another thread in the meantime).

在你的情况下,发生的是两个线程几乎同时执行了一个 InterlockedIncrement 2,然后是2到3.然后,两个线程都读取 thread.threadCount ,并返回3(然后减去1,得到最终结果2)。

In your case, what happens is that two threads did an InterlockedIncrement nearly simultaneously, incrementing it from 1 to 2, then 2 to 3. Both threads then read thread.threadCount and got 3 back (then subtracted 1 to get a final result of 2).

正确的代码是

LONG tidUnique = InterlockedIncrement(&(thread.threadCount));
DWORD tid = (tidUnique-1)%thread.size(); 

唯一递增的值由 InterlockedIncrement 。如果您想要查看唯一值,则需要在计算中使用该值。

The unique incremented value is returned by InterlockedIncrement. You need to use that value in your computations if you want to see the unique value.

这篇关于InterlockedIncrement vs EnterCriticalSection / counter ++ / LeaveCriticalSection的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆