Concurrency in C++
C++11 added a standard threading library. Modern concurrency combines threads, locks, and lock-free atomics.
std::thread
#include <thread>
void worker(int id) {
std::cout << "Thread " << id << std::endl;
}
int main() {
std::thread t1(worker, 1);
std::thread t2(worker, 2);
t1.join();
t2.join();
}
Mutex
#include <mutex>
std::mutex mtx;
int shared = 0;
void increment() {
std::lock_guard<std::mutex> lock(mtx);
++shared;
}
async/future
#include <future>
auto fut = std::async(std::launch::async, [] {
return compute();
});
int result = fut.get();
Atomics
#include <atomic>
std::atomic<int> counter{0};
counter.fetch_add(1, std::memory_order_relaxed);
Condition Variable
std::condition_variable cv;
std::unique_lock lock(mtx);
cv.wait(lock, []{ return ready; });
Common Pitfalls
- Ignoring compiler or linter warnings until they become production bugs.
- Skipping error handling on I/O, allocation, and network operations.
- Using outdated patterns when modern idioms exist in your language version.
- Testing only the happy path without edge cases and failure modes.
Best Practices
- Write tests alongside implementation, not after.
- Prefer explicit, readable code over clever one-liners.
- Use the standard library before reaching for third-party dependencies.
- Profile before optimizing; measure after.
- Document public APIs and non-obvious invariants.
Memory and Performance Notes
Lock contention kills scalability. Prefer lock-free structures or thread-local data when possible.
Exercise
Implement a thread-safe queue using mutex and condition_variable.
Hint: Always join or detach threads. Destroying a joinable thread calls std::terminate.
Real-World Application
Production codebases combine these fundamentals with logging, metrics, and error recovery. Study mature open-source projects in this language for idiomatic patterns.
Summary
Master this topic through hands-on practice before advancing to the next section in the learning path.
Debugging Checklist
- Reproduce with minimal input.
- Read error messages completely.
- Binary-search the problem space by commenting out code.
- Compare against a known-good reference implementation.
- Write a regression test once fixed.
Quick Reference
Review the code examples on this page and type them manually — muscle memory accelerates learning.
Further Reading
C++ Core Guidelines, cppreference.com, and Effective Modern C++ by Scott Meyers.
Real-World Context
These patterns appear in Chromium, Unreal Engine, PostgreSQL, and countless production systems.
Additional Examples
Consider how this topic applies in a larger project:
// Break the problem into smaller functions
// Test each function independently
// Integrate incrementally
Working through variations of the examples above builds deeper understanding than reading alone.
Interview and Review Questions
- Explain the core concept of this topic in your own words.
- What happens when this code runs with edge-case input (empty, null, zero, max value)?
- How would you debug a bug related to this topic in production?
- What are the performance implications of the approach shown here?
- How does this feature compare to the equivalent in another language you know?