I'm using Cygwin GCC and run this code:
#include <iostream> #include <thread> #include <vector> using namespace std; unsigned u = 0; void foo() { u++; } int main() { vector<thread> threads; for(int i = 0; i < 1000; i++) { threads.push_back (thread (foo)); } for (auto& t : threads) t.join(); cout << u << endl; return 0; } Compiled with the line: g++ -Wall -fexceptions -g -std=c++14 -c main.cpp -o main.o.
It prints 1000, which is correct. However, I expected a lesser number due to threads overwriting a previously incremented value. Why does this code not suffer from mutual access?
My test machine has 4 cores, and I put no restrictions on the program that I know of.
The problem persists when replacing the content of the shared foo with something more complex, e.g.
if (u % 3 == 0) { u += 4; } else { u -= 1; }
uback to memory. The CPU will actually do amazing things like notice that the memory line foruisn't in the CPU's cache and it will restart the increment operation. This is why going from x86 to other architectures can be an eye opening experience!while true; do res=$(./a.out); if [[ $res != 1000 ]]; then echo $res; break; fi; done;prints 999 or 998 on my system.