While investigating some scenario's in C++ (11) regarding multithreading, I ran into this strange (to me) situation.
I'm running the increment function below in 2 threads, passing in the address of a shared variable. The core code is this:
static std::mutex mtx; static void increment(int *x, int nofIncrements) { for (int i = 0; i < nofIncrements; i++) { mtx.lock(); (*x)++; mtx.unlock(); } } As you can see a mutex is used to lock the increment operation (inefficient, I know the right solution is to use atomic but I'm trying to understand what's going on).
This code is run in 2 threads with a value for nofIncrements = 100000, which means that I expect the final value to be 200000. However, sometimes I get 200001 which I can't explain...
The full class (available in this gist https://gist.github.com/anonymous/4d218dce2a43a06abe6a):
class LockedIncrement { int _nofIncrements; int _counter; static std::mutex mtx; static void increment(int *x, int nofIncrements) { for (int i = 0; i < nofIncrements; i++) { mtx.lock(); (*x)++; mtx.unlock(); } } public: LockedIncrement(int nofIncrements) { _nofIncrements = nofIncrements; } void DoTest() { std::thread t1(increment, &_counter, _nofIncrements); std::thread t2(increment, &_counter, _nofIncrements); t1.join(); t2.join(); std::cout << "Counter = " << _counter << " (expected " << 2 * _nofIncrements << ")\n"; } }; The test can be run like this:
int main(int argc, char* argv[]) { auto nofIncrements = 1000000; std::cout << "locked increment \n\n"; auto test = LockedIncrement(nofIncrements); test.DoTest(); }