std:: lock_guard
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Member functions | ||||
|
定义于头文件
<mutex>
|
||
|
template
<
class
Mutex
>
class lock_guard ; |
(C++11 起) | |
lock_guard
类是一个互斥量包装器,它提供了一种便捷的
RAII 风格
机制,用于在作用域块期间持有互斥量。
当创建
lock_guard
对象时,它会尝试获取所给互斥锁的所有权。当控制流离开创建
lock_guard
对象的范围时,
lock_guard
会被析构并释放互斥锁。
lock_guard
类是不可复制的。
目录 |
模板参数
| Mutex | - | 要锁定的互斥量类型。该类型必须满足 BasicLockable 要求 |
成员类型
| 成员类型 | 定义 |
mutex_type
|
Mutex |
成员函数
构造
lock_guard
,可选择性地锁定给定的互斥量
(公开成员函数) |
|
析构
lock_guard
对象,解锁底层互斥量
(公开成员函数) |
|
|
operator=
[deleted]
|
不可复制赋值
(公开成员函数) |
注释
一个常见的初学者错误是忘记为
lock_guard
变量命名,例如写成
std
::
lock_guard
{
mtx
}
。这会构造一个立即被销毁的纯右值对象,从而未能实际构造一个在作用域剩余时间内持有互斥量的锁。
|
std::scoped_lock
为
|
(since C++17) |
示例
演示两个线程对 volatile 变量进行安全与非安全递增操作。
#include <iostream> #include <mutex> #include <string_view> #include <syncstream> #include <thread> volatile int g_i = 0; std::mutex g_i_mutex; // protects g_i void safe_increment(int iterations) { const std::lock_guard<std::mutex> lock(g_i_mutex); while (iterations-- > 0) g_i = g_i + 1; std::cout << "thread #" << std::this_thread::get_id() << ", g_i: " << g_i << '\n'; // g_i_mutex is automatically released when lock goes out of scope } void unsafe_increment(int iterations) { while (iterations-- > 0) g_i = g_i + 1; std::osyncstream(std::cout) << "thread #" << std::this_thread::get_id() << ", g_i: " << g_i << '\n'; } int main() { auto test = [](std::string_view fun_name, auto fun) { g_i = 0; std::cout << fun_name << ":\nbefore, g_i: " << g_i << '\n'; { std::jthread t1(fun, 1'000'000); std::jthread t2(fun, 1'000'000); } std::cout << "after, g_i: " << g_i << "\n\n"; }; test("safe_increment", safe_increment); test("unsafe_increment", unsafe_increment); }
可能的输出:
safe_increment: before, g_i: 0 thread #140121493231360, g_i: 1000000 thread #140121484838656, g_i: 2000000 after, g_i: 2000000 unsafe_increment: before, g_i: 0 thread #140121484838656, g_i: 1028945 thread #140121493231360, g_i: 1034337 after, g_i: 1034337
缺陷报告
以下行为变更缺陷报告被追溯应用于先前发布的C++标准。
| DR | 适用范围 | 发布时的行为 | 正确行为 |
|---|---|---|---|
| LWG 2981 | C++17 |
提供了来自
lock_guard<Mutex>
的冗余推导指南
|
已移除 |
另请参阅
|
(C++11)
|
实现可移动的互斥量所有权包装器
(类模板) |
|
(C++17)
|
避免死锁的多个互斥量RAII包装器
(类模板) |