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 InterlockedIncrementcorrectly.
您的代码未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.threadCountvariable (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 InterlockedIncrementnearly simultaneously, incrementing it from 1 to 2, then 2 to 3. Both threads then read thread.threadCountand 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。如果您想查看唯一值,则需要在计算中使用该值。

