std:: unique_lock
|
定义于头文件
<mutex>
|
||
|
template
<
class
Mutex
>
class unique_lock ; |
(C++11 起) | |
类
unique_lock
是一个通用互斥量所有权包装器,支持延迟锁定、限时锁定尝试、递归锁定、锁所有权转移以及与条件变量配合使用。
类
unique_lock
是可移动的,但不可复制——它满足
MoveConstructible
与
MoveAssignable
的要求,但不满足
CopyConstructible
或
CopyAssignable
的要求。
unique_lock
类满足
BasicLockable
要求。若
Mutex
满足
Lockable
要求,则
unique_lock
亦满足
Lockable
要求(例如:可用于
std::lock
);若
Mutex
满足
TimedLockable
要求,则
unique_lock
亦满足
TimedLockable
要求。
目录 |
模板参数
| Mutex | - | 要锁定的互斥量类型。该类型必须满足 BasicLockable 要求 |
嵌套类型
| 类型 | 定义 |
mutex_type
|
Mutex
|
成员函数
构造一个
unique_lock
,可选择性地锁定(即获取所有权)提供的互斥量
(public member function) |
|
|
解锁(即释放所有权)关联的互斥量(如果当前持有所有权)
(public member function) |
|
|
解锁(即释放所有权)当前互斥量(如果持有),并获取另一个互斥量的所有权
(public member function) |
|
锁定操作 |
|
|
锁定(即获取所有权)关联的互斥量
(public member function) |
|
|
尝试非阻塞地锁定(即获取所有权)关联的互斥量
(public member function) |
|
|
尝试锁定(即获取所有权)关联的
TimedLockable
互斥量,若互斥量在指定时长内不可用则返回
(public member function) |
|
|
尝试锁定(即获取所有权)关联的
TimedLockable
互斥量,若互斥量在到达指定时间点前不可用则返回
(public member function) |
|
|
解锁(即释放所有权)关联的互斥量
(public member function) |
|
修改器 |
|
|
与另一个
std::unique_lock
交换状态
(public member function) |
|
|
解除关联互斥量而不解锁(即不释放所有权)
(public member function) |
|
观察器 |
|
|
返回指向关联互斥量的指针
(public member function) |
|
|
测试锁是否拥有(即已锁定)其关联的互斥量
(public member function) |
|
|
测试锁是否拥有(即已锁定)其关联的互斥量
(public member function) |
|
非成员函数
|
(C++11)
|
特化
std::swap
算法
(函数模板) |
注释
一个常见的初学者错误是“忘记”给
unique_lock
变量命名,例如
std
::
unique_lock
(
mtx
)
;
(这会默认构造一个名为
mtx
的
unique_lock
变量)或
std
::
unique_lock
{
mtx
}
;
(这会构造一个立即被销毁的纯右值对象),从而导致实际上并未构造一个能在整个作用域内持有互斥锁的锁对象。
示例
#include <iostream> #include <mutex> #include <thread> struct Box { explicit Box(int num) : num_things{num} {} int num_things; std::mutex m; }; void transfer(Box& from, Box& to, int num) { // 暂不实际获取锁 std::unique_lock lock1{from.m, std::defer_lock}; std::unique_lock lock2{to.m, std::defer_lock}; // 无死锁地同时锁定两个unique_lock std::lock(lock1, lock2); from.num_things -= num; to.num_things += num; // “from.m”和“to.m”互斥锁将在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 << "\n" "acc2: " << acc2.num_things << '\n'; }
输出:
acc1: 95 acc2: 55
缺陷报告
以下行为变更缺陷报告被追溯应用于先前发布的C++标准。
| DR | 适用范围 | 发布时的行为 | 正确行为 |
|---|---|---|---|
| LWG 2981 | C++17 |
提供了来自
unique_lock<Mutex>
的冗余推导指南
|
已移除 |
参见
|
(C++11)
|
锁定指定的互斥锁,若任一不可用则阻塞
(函数模板) |
|
(C++11)
|
实现严格基于作用域的互斥锁所有权包装器
(类模板) |
|
(C++17)
|
避免死锁的多互斥锁RAII包装器
(类模板) |
|
(C++11)
|
提供基本互斥设施
(类) |