Back to questionsWhat is wrong if two threads run
JuniorDebuggingVery common
What is wrong if two threads run count_up at the same time?
int counter = 0;
void count_up() {
for (int i = 0; i < 100000; ++i) {
++counter;
}
}A data race: unsynchronized writes to counter from two threads are undefined behavior
- Expecting
++counterto be indivisible: it readscounter, adds one and writes the result back. The other thread can act between those steps. - Expecting a predictable shortfall: a data race is undefined behavior, so the standard promises no final value, not even one below
200000.
- Why does a run that prints
200000not prove the program correct? - How does
std::atomic<int>fix this counter without a mutex?
Fix
++counter reads the value, adds one and writes the result back, so the threads must run it one at a time. A mutex locked through std::lock_guard lets one thread at a time reach counter:
#include <mutex>
int counter = 0;
std::mutex m;
void count_up() {
for (int i = 0; i < 100000; ++i) {
std::lock_guard<std::mutex> guard(m);
++counter;
}
}For a single counter, an atomic variable std::atomic<int> counter{0}; works too: its ++ is indivisible, and no mutex is needed.