Benjamin Fiskeaux
Benjamin Fiskeaux

Reputation: 17

Why does my thread counter not always finish?

I think my program has a bug because sometimes when I run my program, it outputs a lower number than 30000, such as 29999. But sometimes it runs correctly and gets to the 30000. My question is how can I fix this and why is it happening.

#include <iostream>
#include <thread>

using namespace std;

int counter;
int i;

void increment()
{
counter++;
}

int main()
{
counter = 0;

cout << "The value in counter is : " << counter << endl;
thread tarr[30000];

    for (i = 0; i < 30000; i++)
    {
        tarr[i] = thread(increment);
    }

    for (i = 0; i < 30000; i++)
    {
        tarr[i].join(); //main thread waits for tarr to finish
    }

cout << "After running 30,000 threads ";
cout << "the value in counter is : " << counter << endl;
return 0;
}

Upvotes: 2

Views: 97

Answers (1)

Tas
Tas

Reputation: 7111

The problem is that counter++ can be broken down into three operations:

  1. Load initial value to register
  2. Increment the value
  3. Store the new value back to memory

A single thread may do the first two steps, then pass up control to another thread to do the same. What this can mean is:

  1. Thread one reads counter as 5
  2. Thread one increments its internal copy to 6
  3. Thread two reads counter as 5
  4. Thread two increments its internal copy to 6
  5. Thread two writes back 6 to counter
  6. Thread one writes back 6 to counter

You should make counter std::atomic, or guard it with a std::mutex:

std::atomic<int> counter;

Upvotes: 2

Related Questions