std::lock_guard

来自cppreference.com
< cpp‎ | thread
 
 
并发支持库
线程
(C++11)
(C++20)
this_thread 命名空间
(C++11)
(C++11)
(C++11)
协作式取消
互斥
通用锁管理
(C++11)
lock_guard
(C++11)
(C++11)
(C++11)
条件变量
(C++11)
信号量
闩与屏障
(C++20)
(C++20)
未来体
(C++11)
(C++11)
(C++11)
安全回收
风险指针
原子类型
(C++11)
(C++20)
原子类型的初始化
(C++11)(C++20 弃用)
(C++11)(C++20 弃用)
内存定序
(C++11)(C++26 弃用)
原子操作的自由函数
原子标志的自由函数
 
 
在标头 <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}。这构造了一个纯右值对象并立即销毁,而并未真正为作用域的剩余部分构造持有互斥体的锁。

std::scoped_lock 给出 lock_guard 的一种替代,用避免死锁的算法提供锁定多个互斥体的能力。

(C++17 起)

[编辑]示例

演示两个线程安全和不安全地增加一个 volatile 变量

#include <iostream>#include <mutex>#include <string_view>#include <syncstream>#include <thread>   volatileint 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> 的冗余推导指引 已移除

[编辑]参阅

实现可移动的互斥体所有权包装器
(类模板)[编辑]
用于多个互斥体的免死锁 RAII 封装器
(类模板)[编辑]
close