std::unique_lock

From cppreference.com
Defined in header <mutex>
template< class Mutex >
class unique_lock;
(since C++11)

The class unique_lock is a general-purpose mutex ownership wrapper allowing deferred locking, timed locking, recursive locking, transfer of lock ownership, and use with condition variables.

The unique_lock class is non-copyable, but it is movable. The supplied Mutex type shall implement the BasicLockable concept.

Contents

[edit] Member types

Type Definition
mutex_type Mutex

[edit] Member functions

constructs a unique_lock, optionally locking the supplied mutex
(public member function)
unlocks the associated mutex, if owned
(public member function)
unlocks the mutex, if owned, and acquires ownership of another
(public member function)
Locking
locks the associated mutex
(public member function)
tries to lock the associated mutex, returns if the mutex is not available
(public member function)
attempts to lock the associated TimedLockable mutex, returns if the mutex has been unavailable for the specified time duration
(public member function)
tries to lock the associated TimedLockable mutex, returns if the mutex has been unavailable until specified time point has been reached
(public member function)
unlocks the associated mutex
(public member function)
Modifiers
swaps state with another std::unique_lock
(public member function)
disassociates the associated mutex without unlocking it
(public member function)
Observers
returns a pointer to the associated mutex
(public member function)
tests whether the lock owns its associated mutex
(public member function)
tests whether the lock owns its associated mutex
(public member function)

[edit] Non-member functions

specialization of std::swap for unique_lock
(function template)

[edit] Example

#include <mutex>
#include <thread>
#include <chrono>
 
struct Box {
    explicit Box(int num) : num_things{num} {}
 
    int num_things;
    std::mutex m;
};
 
void transfer(Box &from, Box &to, int num)
{
    // don't actually take the locks yet
    std::unique_lock<std::mutex> lock1(from.m, std::defer_lock);
    std::unique_lock<std::mutex> lock2(to.m, std::defer_lock);
 
    // lock both unique_locks without deadlock
    std::lock(lock1, lock2);
 
    from.num_things -= num;
    to.num_things += num;
 
    lock1.unlock();
    lock2.unlock();
}
 
int main()
{
    Box acc1(100);
    Box acc2(50);
 
    std::thread t1(transfer, std::ref(acc1), std::ref(acc2), 10);
    std::thread t2(transfer, std::ref(acc2), std::ref(acc1), 5);
 
    t1.join();
    t2.join();
}