std::unique_lock::unique_lock
性病::独特[医]锁::独特[医]锁
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) |
构造一个unique_lock
,可以选择锁定所提供的互斥对象。
1%29构造一个unique_lock
没有关联的互斥物。
2%29移动构造函数。初始化unique_lock
带着...的内容other
叶other
没有关联的互斥物。
3-8%29构造aunique_lock
带着m
作为相关的互斥体。此外:
3%29通过调用m.lock()
如果当前线程已经拥有互斥对象,则此行为是未定义的,除非互斥是递归的。
4%29不锁定相关的互斥体。
5%29尝试通过调用锁定相关互斥锁而不阻塞。m.try_lock()
如果当前线程已经拥有互斥对象,则此行为是未定义的,除非互斥是递归的。
6%29假定调用线程已经拥有m
...
7%29试图通过调用m.try_lock_for(timeout_duration)
.区块直至指定timeout_duration
已过或已取得锁,以第一位为准。可能阻塞时间超过timeout_duration
...
8%29试图通过调用m.try_lock_until(timeout_time)
.区块直至指定timeout_time
已到达或已获得锁,两者以第一位为准。可能会阻塞更长的时间直到timeout_time
已经联系到了。
参数
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 |
例外
1,2,4%29
noexcept
规格:
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';
}
二次
产出:
二次
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584
二次
© cppreference.com
在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。