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; }
When race conditions occur. A race condition occurs when two threads access a shared variable at the same time. The first thread reads the variable, and the second thread reads the same value from the variable.
There are many types of race conditions, although a common type of race condition is when two or more threads attempt to change the same data variable. NOTE: Race conditions are a real problem in Python when using threads, even in the presence of the global interpreter lock (GIL).
A race condition exists when the success of your program depends on the uncontrolled order of completion of two independent threads. Suppose, for example, that you have two threads—one is responsible for opening a file and the other is responsible for writing to the file.
foo()
is so short that each thread probably finishes before the next one even gets spawned. If you add a sleep for a random time in foo()
before the u++
, you may start seeing what you expect.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With