InterlockedIncrement vs EnterCriticalSection / counter ++ / LeaveCriticalSection

I have multi-threaded code (see the question Simple example of a Windows API application pool ), for which I use a counter to identify the stream.

I recommend using InterlockedIncrement to increment this counter in the stream callback function. However, this does not seem to be the correct variable lock, as I ran into some concurrency issues. I replaced InterlockedIncrement using the critical section manually: EnterCriticalSection / counter ++ / LeaveCriticalSection, and now it works fine.

Why is that? Shouldn't both options be strictly equivalent? Please note that I am talking about starting only a couple (about 10) threads.

+5
source share
1 answer

Your code does not use correctly InterlockedIncrement.

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

Performs an atomic increment thread.threadCount, but instead of saving the value with the addition of an atom, you ignore it and return to the variable thread.threadCount(which in the meantime can be increased by another thread).

In your case, what happens is that two threads performed InterlockedIncrementalmost simultaneously, increasing it from 1 to 2, then from 2 to 3. Both threads then read thread.threadCountand got 3 back (then subtracted 1 to get the final result 2).

Correct code

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

InterlockedIncrement. , .

+26

All Articles