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.