Types of Locks: std::unique_lock

This lesson gives an overview of std::unique_lock which is a type of lock used in C++.

Features

In addition to what’s offered by an std::lock_guard, an std::unique_lock enables us to:

  • create it without an associated mutex.
  • create it without locking the associated mutex.
  • explicitly and repeatedly set or release the lock of the associated mutex.
  • move the mutex.
  • try to lock the mutex.
  • delay the lock on the associated mutex.

Methods

The following table shows the methods of an std::unique_lock lk.

Method Description
lk.lock() Locks the associated mutex.
std::lock(lk1, lk2, ... ) Atomically locks the arbitrary number of associated mutexes.
lk.try_lock(), and lk.try_lock_for(relTime), and lk.try_lock_until(absTime) Tries to lock the associated mutex.
lk.release() Releases the mutex. The mutex remains locked.
lk.swap(lk2) and std::swap(lk, lk2) Swaps the locks.
lk.mutex() Returns a pointer to the associated mutex.
lk.owns_lock() Checks if the lock has a mutex.

More on lk.try_lock and lk.release methods

lk.try_lock_for(relTime) needs a relative time duration; lk.try_lock_until(absTime) needs an absolute time point.

lk.try_lock tries to lock the mutex and returns immediately. On success, it returns true, but otherwise, it’s false. In contrast, the methods lk.try_lock_for and lk.try_lock_until block the release until the specified timeout occurs or the lock is acquired, whichever comes first. we should use a steady clock for our time constraint. A steady clock cannot be adjusted.

The method lk.release() returns the mutex; therefore, we have to unlock it manually.

How to solve deadlock with std::unique_lock?

Thanks to std::unique_lock, it is quite easy to lock many mutexes in one atomic step; therefore, we can overcome deadlocks by locking mutexes in a different order. Remember the deadlock from the subsection Issues of Mutexes?

Get hands-on with 1400+ tech skills courses.