Protect shared data and prevent race conditions using std::mutex.
When two or more threads access and modify the same shared data concurrently, you can get a race condition. The result can be corrupted data because one thread might read a value while another thread is in the middle of updating it. To prevent this, you need to ensure mutual exclusion, meaning only one thread can access the critical section (the code that modifies the shared data) at a time. The standard tool for this is `std::mutex`, from the `<mutex>` header. A mutex is like a lock. Before a thread enters a critical section, it must lock the mutex. If another thread tries to lock the same mutex while it's already locked, that thread will be blocked (put to sleep) until the mutex is unlocked. Once the first thread is done with the critical section, it unlocks the mutex, allowing one of the waiting threads to proceed. While you can call `.lock()` and `.unlock()` directly on a mutex, this is error-prone. If an exception is thrown while the mutex is locked, `.unlock()` might never be called, leading to a deadlock. The preferred, safer way is to use RAII-style lock guards like `std::lock_guard` or `std::unique_lock`. For example, `std::lock_guard<std::mutex> guard(myMutex);`. This creates a `guard` object that locks the mutex in its constructor. When the `guard` object goes out of scope (at the end of the block), its destructor is automatically called, which unlocks the mutex. This guarantees the mutex is always released, even if an exception occurs.