staticstruct{intn_someFuncCalled;/* Other stuff */}S;intsomeFunc(){++S.n_someFuncCalled;/* Works no matter how many threads */return0;}
The comment
/* Works no matter how many threads */
is a bit misleading. I'm not entirely sure what it's relating to, but if it's saying that multiple threads can simultaneously increment the counter and the result will be correct, then I'm afraid that's not true.
You would need to protect that counter with a mutex or somesuch or use an atomic type.
Hmm, OK, an integer can generally be considered atomic as when it's updated, you always see either it's old or new value and not something inbetween.
However this does not help with the case of multiple threads trying to update an integer. Using a normal int type and doing a ++ on it will be three instructions; load/add/store.
So
++S.n_someFuncCalled;
translates to something like the following assembly
Lets say the counter has a value of 10 and two threads are coming to increment it.
So thread a could be between the add and second mov, when thread b comes in and does the first mov.
So thread A did 10 + 1, but before it copied the result back to memory, thread B came in and copied 10 into the register and then does the add, meanwhile thread A has now put 11 back into memory (correct), however thread B is doing 10 + 1 and so also puts 11 back in memory, so we are left with a = 11 and not 12...
This from the link I provided above also gives a hint
Objects of atomic types are the only objects that are free from data races, that is, they may be modified by two threads concurrently or modified by one and read by another.
This is easy to test yourself with a small program that has two threads updating an integer, try with and without locking... the example in the link above shows what you can expect to see...
You are correct, thanks for pointing out the oversight. I got the 20 minute lecture this morning from my son, and specifying atomic is the best practice for code to work on a variety of hardware platforms. Thanks for pointing this out!
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Hi,
In this example
The comment
is a bit misleading. I'm not entirely sure what it's relating to, but if it's saying that multiple threads can simultaneously increment the counter and the result will be correct, then I'm afraid that's not true.
You would need to protect that counter with a mutex or somesuch or use an atomic type.
Incrementing an integer is atomic.
Hmm, OK, an integer can generally be considered atomic as when it's updated, you always see either it's old or new value and not something inbetween.
However this does not help with the case of multiple threads trying to update an integer. Using a normal int type and doing a ++ on it will be three instructions; load/add/store.
So
translates to something like the following assembly
Lets say the counter has a value of 10 and two threads are coming to increment it.
So thread a could be between the add and second mov, when thread b comes in and does the first mov.
So thread A did 10 + 1, but before it copied the result back to memory, thread B came in and copied 10 into the register and then does the add, meanwhile thread A has now put 11 back into memory (correct), however thread B is doing 10 + 1 and so also puts 11 back in memory, so we are left with a = 11 and not 12...
This from the link I provided above also gives a hint
This is easy to test yourself with a small program that has two threads updating an integer, try with and without locking... the example in the link above shows what you can expect to see...
You are correct, thanks for pointing out the oversight. I got the 20 minute lecture this morning from my son, and specifying atomic is the best practice for code to work on a variety of hardware platforms. Thanks for pointing this out!