std::lock_guard
来自cppreference.com
<tbody>
</tbody>
| 在标头 <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= [弃置] |
不可复制赋值 (公开成员函数) |
注解
一种常见的新手错误是“忘记”给 lock_guard 变量命名,例如 std::lock_guard(mtx);(它默认构造了一个名为 mtx 的 lock_guard 变量),或者 std::lock_guard{mtx};(它构造了一个纯右值对象并立即销毁),而并未真正为作用域的剩余部分构造持有互斥体的锁。
|
std::scoped_lock 给出 |
(C++17 起) |
示例
演示两个线程安全和不安全地增加一个 volatile 变量
运行此代码
#include <iostream>
#include <mutex>
#include <string_view>
#include <syncstream>
#include <thread>
volatile int g_i = 0;
std::mutex g_i_mutex; // 保护 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 << "线程 #" << std::this_thread::get_id() << ", g_i: " << g_i << '\n';
// g_i_mutex 在锁离开作用域时自动释放
}
void unsafe_increment(int iterations)
{
while (iterations-- > 0)
g_i = g_i + 1;
std::osyncstream(std::cout) << "线程 #" << 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 << ":\n前, g_i: " << g_i << '\n';
{
std::jthread t1(fun, 1'000'000);
std::jthread t2(fun, 1'000'000);
}
std::cout << "后, g_i: " << g_i << "\n\n";
};
test("safe_increment", safe_increment);
test("unsafe_increment", unsafe_increment);
}
可能的输出:
safe_increment:
前, g_i: 0
线程 #140121493231360, g_i: 1000000
线程 #140121484838656, g_i: 2000000
后, g_i: 2000000
unsafe_increment:
前, g_i: 0
线程 #140121484838656, g_i: 1028945
线程 #140121493231360, g_i: 1034337
后, g_i: 1034337
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
| 缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
|---|---|---|---|
| LWG 2981 | C++17 | 曾提供来自 lock_guard<Mutex> 的冗余推导指引
|
已移除 |
参阅
(C++11) |
实现可移动的互斥体所有权包装器 (类模板) |
(C++17) |
用于多个互斥体的免死锁 RAII 封装器 (类模板) |