windows InterlockedIncrement vs EnterCriticalSection/counter++/LeaveCriticalSection
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8393990/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
InterlockedIncrement vs EnterCriticalSection/counter++/LeaveCriticalSection
提问by nbonneel
I have some multithreaded code (see question Windows API Thread Pool simple example) for which I am using a counter to identify a thread.
我有一些多线程代码(请参阅问题Windows API 线程池简单示例),我使用计数器来识别线程。
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.
我被建议使用 InterlockedIncrement 来增加线程回调函数中的这个计数器。但是,这似乎没有正确锁定变量,因为我遇到了一些并发问题。我通过手动使用临界区替换了 InterlockedIncrement:EnterCriticalSection/counter++/LeaveCriticalSection,现在它可以完美运行。
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.
为什么会这样?这两个选项不应该严格等效吗?请注意,我说的是只启动几个(大约 10 个)线程。
回答by Raymond Chen
Your code is not using InterlockedIncrement
correctly.
您的代码未InterlockedIncrement
正确使用。
InterlockedIncrement(&(thread.threadCount));
DWORD tid = (thread.threadCount-1)%thread.size();
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).
这将执行 的原子增量thread.threadCount
,但不是保存原子增量的值,而是忽略它并返回到thread.threadCount
变量(在此期间它可能已被另一个线程增量)。
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).
在您的情况下,发生的情况是两个线程InterlockedIncrement
几乎同时执行,将其从 1 增加到 2,然后从 2 增加到 3。然后两个线程都读取thread.threadCount
并返回 3(然后减去 1 得到 2 的最终结果)。
The correct code is
正确的代码是
LONG tidUnique = InterlockedIncrement(&(thread.threadCount));
DWORD tid = (tidUnique-1)%thread.size();
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
。如果您想查看唯一值,则需要在计算中使用该值。