Concurrency Fundamentals • Race Conditions & Critical SectionsMedium⏱️ ~3 min
Data Races vs Race Conditions
Key Insight
Data races and race conditions are related but distinct. You can have one without the other. Understanding the difference matters for both debugging and choosing tools.
Data Race vs Race Condition
Data Race Without Race Condition
Two threads write the same value to a variable. The final state is correct regardless of order, but it is still a data race (undefined behavior in C/C++).
Race Condition Without Data Race
Two threads use proper locking but the logic is still timing-dependent. Example: Thread A locks, checks empty, unlocks. Thread B locks, adds item, unlocks. Thread A proceeds as if empty. All accesses synchronized, still wrong.
Why It Matters
Tools detect data races: ThreadSanitizer, Helgrind can find data races automatically. They cannot find race conditions.
Fixing data races is not enough: Your code can be data-race-free and still have race conditions. You need to think about correctness, not just synchronization.
Summary: Data race = memory access problem (tool-detectable). Race condition = logic problem (requires human reasoning).
💡 Key Takeaways
✓Data race: unsynchronized concurrent memory access where at least one is a write. Undefined behavior in C/C++.
✓Race condition: program correctness depends on timing. Can occur even with proper synchronization.
✓Data races are detectable by tools like ThreadSanitizer, Helgrind, or Go race detector. Run tests with race detection enabled.
✓Race conditions require semantic understanding to detect. They represent logic errors, not memory safety violations.
✓Eliminating data races does not eliminate race conditions. You can have correct synchronization but wrong logic.
📌 Examples
1Data race free but buggy: lock(); if (queue.empty()) { unlock(); return; } item = queue.pop(); unlock(); Another thread could pop between empty check and pop if the lock is released.
2Data race: int x; thread1: x = 1; thread2: print(x). Without synchronization, thread2 might see 0, 1, or garbage.