If more than one thread is sharing a variable, you have to coordinate the access. That’s the job for mutexes and locks in C++.
A data race is a state in which at least two threads access a shared data at the same time, and at least one of the threads is a writer. Therefore the program has undefined behavior.
You can observe very well the interleaving of threads if a few threads write to
std::cout. The output stream
std::cout is, in this case, the shared variable.