std::unique_lock

The std::unique_lock class provides more flexibility as compared to std::lock_guard. It provides features like manual locking, unlocking, deferred locking, transfer of ownership, and many more to the users. std::unique_lock requires explicit locking and unlocking, it doesn’t automatically acquire and release lock like std::lock_guard. Following is the syntax to use std::unique_lock in C++:

Syntax

std::unique_lock<std::mutex> lock(mutex);
// Mutex is now locked

// Write the Code for Critical section

// Optional: manually unlock before the lock object goes out of scope
lock.unlock();

// Optional: re-lock if needed
lock.lock();

where lock() and unlock() are methods to acquire and release the mutex.

C++ Program using std::unique_lock

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

C++
// C++ Program using std::unique_lock
#include <mutex>
#include <thread>
#include <iostream>
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<mutex> 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 std::unique_lock:

  • Flexibility: Can lock and unlock multiple times within its scope.
  • Deferred Locking: This can be constructed without locking the mutex immediately.
  • Timed Locking: Supports times and try-locking operations.
  • Ownership Transfer: It allows transferring mutex ownership to another std::unique_lock.

Usage

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

  • You need more control over the locking mechanism including ability to lock and unlock manually.
  • You need to defer locking or conditionally lock a mutex.
  • You require timed locking to prevent blocking indefinitely.
  • You need to transfer lock ownership between different scopes or threads.

std::unique_lock or std::lock_guard: Which Is Better?

In C++, to manage access to shared resources, the STL (standard template library) of C++, provides synchronization mechanisms such as std::lock_guard and std::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 std::unique_lock and std::lock_guard in C++

Similar Reads

std::unique_lock

The std::unique_lock class provides more flexibility as compared to std::lock_guard. It provides features like manual locking, unlocking, deferred locking, transfer of ownership, and many more to the users. std::unique_lock requires explicit locking and unlocking, it doesn’t automatically acquire and release lock like std::lock_guard. Following is the syntax to use std::unique_lock in C++:...

std::lock_guard

std::lock_guard is a simple RAII-style (Resource Acquisition Is Initialization) mutex wrapper that locks a mutex on creation and automatically unlocks it upon destruction. It provides a straightforward way to ensure that a mutex is properly released even if an exception is thrown. Following is the syntax to use std::lock_guard in C++:...

Difference between std::lock_guard and std::unique_lock

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

Conclusion

In conclusion, both std::unique_lock and std::lock_guard are powerful tools provided by the C++ standard library for managing mutexes and ensuring thread safety. std::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....