1

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(); } 
1
  • 2
    Why aren't you using appropriate std::lock mechanisms in 1st place? Commented Oct 19, 2014 at 19:32

1 Answer 1

4

The code from gist increments _counter which is not initialized, this is leading to undetermined behaviour. You are lucky to get 200000 and 200001...I'm getting 377232...

LockedIncrement(int nofIncrements) : _nofIncrements( nofIncrements ), _counter ( 0 ) { } 
Sign up to request clarification or add additional context in comments.

1 Comment

argh, of course. Strange though that it is apparently initialized to either 0 or 1 in my case. The definition of 'undefined', I guess. Thanks.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.