#include #include #include using namespace std ; mutex global_mutex; // A global mutex to protect shared data int shared_data = 0; void deferred_lock() { cout << "Thread " << this_thread::get_id() << " is starting." << endl; // Create a unique_lock, but defer locking the mutex // The mutex will NOT be locked upon construction of 'lock' unique_lock lock(global_mutex, defer_lock); // Perform some operations that do not require the mutex cout << "Thread " << this_thread::get_id() << " doing non-critical work..." << endl; this_thread::sleep_for(chrono::milliseconds(100)); // Simulate some work // Now, explicitly acquire the lock when the critical section is needed cout << "Thread " << this_thread::get_id() << " attempting to lock mutex..." << endl; lock.lock(); // This will block if the mutex is already locked by another thread // Critical section: safely modify shared_data shared_data++; cout << "Thread " << this_thread::get_id() << " modified shared_data to: " << shared_data << endl; // Optionally, release the lock early if the critical section is over // and more non-critical work needs to be done within the same scope lock.unlock(); cout << "Thread " << this_thread::get_id() << " unlocked mutex and doing more non-critical work." << endl; this_thread::sleep_for(chrono::milliseconds(50)); // If the lock is needed again, it can be re-acquired lock.lock(); shared_data++; cout << "Thread " << this_thread::get_id() << " re-locked mutex and modified shared_data to: " << shared_data << endl; // The mutex will be automatically unlocked when 'lock' goes out of scope // (if it's currently held) cout << "Thread " << this_thread::get_id() << " is finishing." << endl; } int main() { thread t1(deferred_lock); thread t2(deferred_lock); t1.join(); t2.join(); cout << "Final shared_data value: " << shared_data << endl; return 0; }