unique_lock(); | (1) | (since C++11) |
unique_lock( unique_lock&& other ); | (2) | (since C++11) |
explicit unique_lock( mutex_type& m ); | (3) | (since C++11) |
unique_lock( mutex_type& m, std::defer_lock_t t ); | (4) | (since C++11) |
unique_lock( mutex_type& m, std::try_to_lock_t t ); | (5) | (since C++11) |
unique_lock( mutex_type& m, std::adopt_lock_t t ); | (6) | (since C++11) |
template< class Rep, class Period > unique_lock( mutex_type& m, const std::chrono::duration<Rep,Period>& timeout_duration ); | (7) | (since C++11) |
template< class Clock, class Duration > unique_lock( mutex_type& m, const std::chrono::time_point<Clock,Duration>& timeout_time ); | (8) | (since C++11) |
Constructs a unique_lock
, optionally locking the supplied mutex.
unique_lock
with no associated mutex.unique_lock
with the contents of other
. Leaves other
with no associated mutex.unique_lock
with m
as the associated mutex. Additionally:m.lock()
. The behavior is undefined if the current thread already owns the mutex except when the mutex is recursive.m.try_lock()
. The behavior is undefined if the current thread already owns the mutex except when the mutex is recursive.m
.m.try_lock_for(timeout_duration)
. Blocks until specified timeout_duration
has elapsed or the lock is acquired, whichever comes first. May block for longer than timeout_duration
.m.try_lock_until(timeout_time)
. Blocks until specified timeout_time
has been reached or the lock is acquired, whichever comes first. May block for longer than until timeout_time
has been reached.other | - | another unique_lock to initialize the state with |
m | - | mutex to associate with the lock and optionally acquire ownership of |
t | - | tag parameter used to select constructors with different locking strategies |
timeout_duration | - | maximum duration to block for |
timeout_time | - | maximum time point to block until |
noexcept
specification: noexcept
#include <cassert> #include <iostream> // std::cout #include <thread> #include <vector> #include <mutex> class Number; std::ostream& operator<<(std::ostream& stream, const Number& number); class Number { public: Number() : v_(1) {} // thread-safe update of 'a' and 'b' static void update(Number& a, Number& b, bool order) { // do not lock 'mutex_' of 'a' and 'b' sequentially, // two sequential lock may lead to deadlock, // that's why 'std::lock' exists (see below) GuardLock lock_a(a.mutex_, std::defer_lock); GuardLock lock_b(b.mutex_, std::defer_lock); // mutexes is not locked assert(!lock_a.owns_lock()); assert(!lock_b.owns_lock()); // unspecified series of calls... std::lock(lock_a, lock_b); // Result: 'a.mutex_' and 'b.mutex_' is in locked state // 'a' and 'b' can be modified safety assert(lock_a.owns_lock()); assert(lock_b.owns_lock()); if (order) { a.v_ += b.v_; b.v_ += a.v_; std::cout << a << b; } else { b.v_ += a.v_; a.v_ += b.v_; std::cout << b << a; } // 'lock_a' and 'lock_b' will be destroyed, // unlocking 'a.mutex_' and 'b.mutex_' } // not thread-safe; used before thread creation or in thread-safe 'update' std::ostream& print(std::ostream& stream) const { stream << v_ << " "; return stream; } private: using Mutex = std::mutex; using GuardLock = std::unique_lock<Mutex>; Mutex mutex_; int v_; }; // not thread-safe; see 'Number::print' std::ostream& operator<<(std::ostream& stream, const Number& number) { return number.print(stream); } int main() { Number a, b; std::cout << a << b; std::vector<std::thread> threads; for (unsigned i = 0; i < 4; ++i) { // without 'std::lock' deadlock may occur in this situation: // thread #1 lock 'a.mutex_' // thread #2 lock 'b.mutex_' // thread #1 try to lock 'b.mutex_' and blocked (it's locked by #2) // thread #2 try to lock 'a.mutex_' and blocked (it's locked by #1) // ... deadlock threads.emplace_back(Number::update, std::ref(a), std::ref(b), true); // #1 threads.emplace_back(Number::update, std::ref(b), std::ref(a), false); // #2 } for (auto& i: threads) { i.join(); } std::cout << '\n'; }
Output:
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
http://en.cppreference.com/w/cpp/thread/unique_lock/unique_lock