unique_lock or lock_guard: Which Is Better? (original) (raw)

Last Updated : 8 May, 2025

In C++, to manage access to shared resources, the STL (standard template library) of C++, provides synchronization mechanisms such as **lock_guard and **unique_lock. Both are useful for managing mutex but have different features and use cases.

In this article, we will discuss the advantages, disadvantages, differences, and use cases of both unique_lock and lock_guard in C++

unique_lock

**unique_lock offers more flexibility than **lock_guard. It provides features like manual locking and unlocking, deferred locking, and ownership transfer. Unlike lock_guard, which automatically locks and unlocks the mutex, unique_lock requires explicit calls to lock and unlock. The following is the syntax to use unique_lock in C++:

**Syntax

C++ `

shared_lock Name(myMutex, lockingBehavior);

`

where,

Example

The following program illustrates the use of unique_lock in C++:

C++ `

// C++ Program using std::unique_lock #include #include #include using namespace std;

// Global mutex to protect shared_data mutex mtx;

// Shared data variable int shared_data = 0;

// Function to increment shared_data void increment_data() { // Create a unique_lock object, but defer locking the mutex unique_lock lock(mtx, defer_lock);

// Explicitly acquire the lock
lock.lock(); 

// Critical section: safely modify shared_data
shared_data += 2;

// Manually release the lock
lock.unlock(); 

}

int main() { // Create two threads that run the increment_data function thread t1(increment_data); thread t2(increment_data);

// Wait for both threads to finish
t1.join();
t2.join();

// Output the value of shared_data
cout << "Value of shared variable: " << shared_data;
return 0;

}

`

**Output

Value of shared variable: 4

**Time Complexity: O(1)
**Auxiliary Space: O(1)

**Key Features

Following are some key features of unique_lock:

**Usage

Following are the use cases when you should consider using unique_lock:

lock_guard

In C++, **lock_guard is a simple class that is used to manage the locking and unlocking of a mutex. Its main purpose is to automatically lock a mutex when it is created and automatically unlock it when the lock_guard object goes out of scope. Following is the syntax to use lock_guard in C++:

Syntax

C++ `

lock_guard name(myMutex);

`

where,

Example

The following program illustrates the use of lock_guard in C++:

C++ `

// C++ Program using std::lock_guard #include #include #include using namespace std;

// Global mutex to protect shared_data mutex mtx;

// Shared data variable int shared_data = 0;

// Function to increment shared_data void increment_data() { // Create a lock_guard object which locks the mutex lock_guard lock(mtx);

// Critical section: safely modify shared_data
shared_data+=2;

// Lock is automatically released when 'lock' goes out of scope

}

int main() { // Create two threads that run the increment_data function thread t1(increment_data); thread t2(increment_data);

// Wait for both threads to finish
t1.join();
t2.join();

// Output the value of shared_data
cout << "Value of shared variable: " << shared_data;

return 0;

}

`

**Output

Value of shared variable: 4

**Time Complexity: O(1)
**Auxiliary Space: O(1)

**Key Features

Following are some key features of unique_lock:

**Usage

Following are the use cases when you should consider using lock_guard:

Difference between lock_guard and unique_lock

Following are some key differences between lock_guard and unique_lock in C++:

Features lock_guard unique_lock
Complexity Simple and minimal overhead. It is more complex and have additional overhead due to extra features.
Locking behavior Locks mutex upon construction and destruction. Can lock and unlock multiple times within its scope and supports deferred locking.
Flexibility No manual control over locking and unlocking. There is manual control over locking and unlocking.
Deferred Locking Not supported. Supported.
Timed Locking Not supported. Supported.
Ownership Transfer Not supported. Supported.
Ideal Usage Used where simple and single-scope locking is needed. Used in complex scenarios needing lock control and flexibility.
Exception Safety Guarantees unlock on destruction It guarantees unlock on destruction more control may increase error risk if misused
Overhead Minimal Slightly higher due to additional features.
Example Use Case Simple critical sections. Conditional locking, timed locking and transferring lock ownership.

Conclusion

In conclusion, both unique_lock and lock_guard are powerful tools provided by the C++ standard library for managing mutexes and ensuring thread safety. lock_guard offers a simple, efficient way to lock and unlock a mutex within a scope, making it ideal for straightforward locking needs.Choosing between them depends on the specific requirements of your code.