The original text reads as follows:
Http://en.cppreference.com/w/cpp/thread/unique_lock
Http://en.cppreference.com/w/cpp/thread/unique_lock/unique_lock
Http://en.cppreference.com/w/cpp/thread/unique_lock/~unique_lock
Http://en.cppreference.com/w/cpp/thread/unique_lock/operator%3D
Http://en.cppreference.com/w/cpp/thread/unique_lock/lock
Http://en.cppreference.com/w/cpp/thread/unique_lock/try_lock
Http://en.cppreference.com/w/cpp/thread/unique_lock/try_lock_for
Http://en.cppreference.com/w/cpp/thread/unique_lock/try_lock_until
Http://en.cppreference.com/w/cpp/thread/unique_lock/unlock
Http://en.cppreference.com/w/cpp/thread/unique_lock/mutex
Http://en.cppreference.com/w/cpp/thread/unique_lock/owns_lock
Http://en.cppreference.com/w/cpp/thread/unique_lock/operator_bool Std::unique_lock
defined in the header file.
Template <class mutex> (since c++11)
class Unique_lock;
Class Unique_lock is a generic mutex wrapper that provides delay locking (deferred locking), timed attempts (time-constrained attempts), recursive locking (recursive locking), The conversion of the lock master, and the use of the conditional variable.
Class Unique_lock is movable, but not copyable-it meets Moveconstructible and moveassignable, but does not meet copyconstructible and copyassignable .
Class Unique_lock meet the requirements of basiclockable. If the mutex satisfies the requirements of the lockable, then Unique_lock also satisfies the lockable requirements (for example, it can be used for std::lock), and if the mutex meets the timedlockable requirements, Unique_lock also satisfies Timedlockable's requirements. Template Parameters
Mutex-the type of mutex used for locking. The type must meet the requirements of the basiclockable. Constructors
(1) Unique_lock ();
(2) Unique_lock (unique_lock&& other);
(3) Explicit Unique_lock (mutex_type& m);
(4) Unique_lock (mutex_type& m, std::d efer_lock_t t);
(5) Unique_lock (mutex_type& m, std::try_to_lock_t t);
(6) Unique_lock (mutex_type& m, std::adopt_lock_t t);
(7) template< class Rep, class Period >
unique_lock (mutex_type& m,
const Std::chrono::d uration< rep,period>& timeout_duration);
(8) template< class Clock, class Duration >
unique_lock (mutex_type& m,
const STD::CHRONO::TIME_ point<clock,duration>& timeout_time);
(1) Unique_lock ();
Constructs a unique_lock with no associated mutex
(2) Unique_lock (unique_lock&& other);
The move constructor, which uses the contents of other to construct the Unique_lock. Makes the other a unique_lock without a mutex association.
(3)-(8) constructs a unique_lock with a mutex associated with M, in addition:
(3) Explicit Unique_lock (mutex_type& m);
Lock the associated mutex by calling M.lock (). If the current thread already has a mutex and is not a recursive mutex, then the behavior is undefined.
(4) Unique_lock (mutex_type& m, std::d efer_lock_t t);
The associated mutex is not locked.
(5) Unique_lock (mutex_type& m, std::try_to_lock_t t);
Attempt to lock the associated mutex without blocking by calling M.try_lock (). If the current thread already has a mutex and is not a recursive mutex, the behavior is undefined.
(6) Unique_lock (mutex_type& m, std::adopt_lock_t t);
Suppose the thread already owns M.
(7)
template< class Rep, class Period >
unique_lock (mutex_type& m, const Std::chrono::d uration<rep,period >& timeout_duration);
An attempt was made to lock an associated mutex by calling M.try_lock_for (Timeout_duration). Block until timeout or lock succeeds. It can also be blocked longer than the time_duration time.
(8)
template< class Clock, class Duration >
unique_lock (mutex_type& m, const std::chrono::time_point< clock,duration>& timeout_time);
Attempts to lock the associated mutex by calling M.try_lock_until (Timeout_time). Blocks until a specified point in time arrives or locks are successful. may still block for a moment after the specified time arrives.
Sample programs:
#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) {//Does not lock ' mutex_ ' ' A ' and ' B ' sequentially,//two sequential lock could lead
To deadlock,//That ' s why ' std::lock ' exists (* below) Guardlock lock_a (a.mutex_, std::d efer_lock);
Guardlock Lock_b (b.mutex_, std::d efer_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_ ' are in locked state//' A ' and ' B ' can be modified safety assert (lock_a.owns_l
Ock ());
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 ' would 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 {str
EAM << v_ << "";
return stream;
} private:using Mutex = Std::mutex;
Using Guardlock = std::unique_lock<mutex>;
Mutex mutex_;
int v_;
}; Not thread-safe; ' Number::p rint ' std::ostream& operator<< (std::ostream& stream, const number& number) {return numb
Er.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 could 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)//th Read #2 try to lock ' a.mutex_ ' and blocked (it's locked by #1)//... deadlock Threads.emplace_back (NUMBER::UPDA Te, 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
destructor
Destroy this Unique_lock object. If *this has an associated mutex at this time and has acquired it, the mutex is unlocked. assignment operator operator =
unique_lock& operator= (unique_lock&& other); (Since c++11)
The move assignment operator. Use the contents of other to assign to yourself.
If *this already owns a mutex and locks it before this call, the call unlocks the mutex. Std::unique_lock::lock function
void Lock (); (Since c++11)
Locks the associated mutex. Efficiently invoke the mutex ()->lock ().
Abnormal:
-Throws the exception thrown by the mutex ()->lock ().
-If there is no associated mutex, the Std::system_error is thrown, and the error code you carry is std::errc::operation_not_permitted.
-If the mutex has been locked by this unique_lock (in other words, Owns_lock is true) then Std::system_error will be thrown and the error code is Std::errc::resource_deadlock_ Would_occur.
See sample program:
#include <mutex> #include <thread> #include <iostream> #include <vector> #include <chrono
> int main () {int counter = 0;
Std::mutex Counter_mutex;
Std::vector<std::thread> threads; Auto Worker_task = [ampersand] (int id) {//note, which is just lock!
The document of the constructor.
std::unique_lock<std::mutex> Lock (Counter_mutex);
++counter;
Std::cout << ID << ", initial counter:" << counter << ' \ n ';
Lock.unlock (); Don ' t hold the lock while we simulate a expensive operation Std::this_thread::sleep_for (1
));
Lock.lock ();
++counter;
Std::cout << ID << ", Final counter:" << counter << ' \ n ';
};
for (int i = 0, I < ++i) {//vector::p ush_back () cannot work due to std::thread.
Threads.emplace_back (Worker_task, i); } for (Auto &thread:threads) Thread.Join (); /** Possible output:0, initial counter:1 1, initial counter:2 2, initial counter:3 3, initial counter:4 4, Initia L Counter:5 5, initial counter:6 6, initial counter:7 7, initial counter:8 8, initial counter:9 9, initial counter:1 0 1, Final counter:11 0, final Counter:12 3, final counter:13 5, Final counter:14 2, Final counter:15 4, final Counte
R:16 7, Final counter:17 9, final counter:18 6, final counter:19 8, final counter:20 **/
Std::unique_lock::try_lock function
BOOL Try_lock (); (Since c++11)
An attempt was made to lock an associated mutex without blocking it. Efficiently invoke the mutex ()->try_lock ().
If there is no associated mutex or the mutex is locked by the Unique_lock, then Std::system_error is thrown.
Abnormal:
-any exception thrown by the mutex ()->try_lock () will be thrown (the mutex type will not be thrown by Try_lock, but a custom lockable type may be thrown).
-If there is no associated mutex, then the Std::system_error is thrown and the error code is std::errc::operation_not_permitted.
-If the mutex has been locked by this unique_lock, Std::system_error will also be thrown, and the error code is std::errc::resource_deadlock_would_occur. std::unique_lock::try_lock_for function
Template Std::unique_lock::unlock function
void unlock (); (Since c++11)
Unlocks the associated mutex.
If no mutex is associated or the mutex is locked, the std::system_error is thrown.
Abnormal:
-any exception thrown by the mutex ()->unlock () will be thrown.
-If no mutex is associated or the mutex is not locked, the std::system_error is thrown, and the error code is std::errc::operation_not_permitted. Std::unique_lock::mutex function
mutex_type* mutex () const; (Since c++11)
Returns a pointer to the associated mutex, or returns a null pointer if there is no associated mutex. Std::unique_lock::owns_lock function
BOOL Owns_lock () const; (Since c++11)
Check to see if *this has locked the mutex.
Yes, returns TRUE, otherwise it returns false. std::unique_lock::operator bool Function
Explicit operator bool () const; (Since c++11)
Check to see if *this has locked a mutex. efficiently invoke Owns_lock ().
Yes, returns TRUE, otherwise it returns false. Sample Programs
#include <mutex> #include <thread> #include <chrono> #include <iostream> struct Box {Explici
T Box (int num): num_things{num} {} int num_things;
Std::mutex m;
}; void Transfer (Box &a, box &b, int num) {//don ' t actually take the locks yet
Ex> Lock1 (a.m, std::d efer_lock);
Std::unique_lock<std::mutex> Lock2 (B.M, std::d efer_lock);
Lock both Unique_locks without deadlock Std::lock (Lock1, Lock2);
a.num_things = num;
B.num_things + = num;
' a.m ' and ' b.m ' mutexes unlocked outside of ' unique_lock '} 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 ();
Std::cout << "ACC1:" << acc1.num_things << Std::endl;
Std::cout << "ACC2:" << acc2.num_things << Std::endl;} /** Output:acc1:95 acc2:55 **/
The original example program does not have any output and the name of the variable is confusing, so it is slightly modified. )
Finish