[C++11 threads] Why isn't this giving me the wrong number?

Isn't this supposed to give me some sort of race condition? Thanks.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <thread>

using namespace std;

void f(int &n){
  for( int i = 0; i < 50000; i++) n++;
}
void h(int &n){
  for( int i = 0; i < 50000; i++) n++;
}
void g(int &n){
 for( int i = 0; i < 50000; i++) n++;
}

int main(){
  int n = 0;
  thread t(f, ref(n));
  thread t2(h, ref(n));
  thread t3(g, ref(n));
  t.join();t2.join();t3.join();
  cout << n << endl;
  cin.get();
}
> Isn't this supposed to give me some sort of race condition? Thanks.

It can give you some sort of race condition. (depends on: is increment of an int atomic on the particular implementation?)
Most compilers will replace the loop with n += 50000, and because creation of a thread takes much longer than incrementing an integer, there may be no race condition.

Use std::atomic<int> and you are safe everywhere.
http://en.cppreference.com/w/cpp/atomic/atomic
n++ is one processor instruction if you do not using return value. It is probably just optimized your code (loop elimination to n+=50000) and separated all access to n.
Try
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <thread>
using namespace std;

volatile int n = 0;

void f(){
  for( int i = 0; i < 50000; i++) n++;
}
void h(){
  for( int i = 0; i < 50000; i++) n++;
}
void g(){
 for( int i = 0; i < 50000; i++) n++;
}

int main()
{
  thread t(f);
  thread t2(h);
  thread t3(g);
  t.join();t2.join();t3.join();
  cout << n << endl;
  cin.get();
}
And you will see races in its finest

TL;DR: Your compiler optimized your code because it is small and predictable.
Last edited on
Thanks both!

Well explained.
Topic archived. No new replies allowed.