0

0

C++怎么使用thread C++线程同步与互斥锁【深度】

尼克

尼克

发布时间:2026-03-10 14:26:03

|

964人浏览过

|

来源于php中文网

原创

std::thread 构造后必须 detach 或 join,否则析构时调用 std::terminate() 导致进程崩溃;std::mutex 不可拷贝或移动,需引用捕获;多资源加锁应使用 std::lock() 避免死锁;读多写少场景优先用 std::shared_mutex;condition_variable 等待必须配合 while 循环和谓词。

c++怎么使用thread c++线程同步与互斥锁【深度】

std::thread 构造后必须 detach 或 join,否则程序崩溃

构造 std::thread 对象后,如果它仍处于“可加入”(joinable)状态,而析构函数被调用(比如线程对象是局部变量,作用域结束),会直接调用 std::terminate() —— 不抛异常,不打印日志,进程立刻退出。这是新手踩得最多、最隐蔽的坑。

  • 必须在对象生命周期结束前显式调用 join()(等待线程结束)或 detach()(移交后台运行)
  • join() 只能调用一次;重复调用或对已 detach() 的线程调用,行为未定义
  • 别在析构函数里写 join() —— 如果线程还在跑,析构卡住;如果线程已结束但没及时 join(),析构时就崩
  • 推荐封装:用 RAII 类(如 scoped_thread)自动 join(),或明确设计为 detach() 场景(如日志上报、心跳发送)

std::mutex 不能拷贝,也不能跨线程传递所有权

std::mutex 是非复制、非移动类型,所有成员函数(包括构造、赋值、拷贝)都被删除。试图把它塞进 std::vector、传给 std::thread 的 lambda 捕获列表(按值捕获)、或者返回一个临时 mutex,编译直接报错:use of deleted function

  • 锁对象通常作为类成员或全局/静态变量存在,生命周期需覆盖所有可能访问它的线程
  • lambda 中需要访问锁时,务必用引用捕获:[&mtx]{ mtx.lock(); ... },而不是 [mtx]{...}
  • 多个资源需加锁时,统一用 std::lock() + std::unique_lock 避免死锁,不要手写 lock()/unlock() 顺序
  • std::recursive_mutex 仅当真需要同一线程多次加同一把锁时才用——多数情况说明设计有问题

std::shared_mutex 在读多写少场景下比 std::mutex 更高效

如果你的临界区主要是并发读、极少写(比如配置缓存、路由表、白名单),std::shared_mutex(C++17 起)允许任意数量线程同时读,但写操作独占。相比所有读也排队的 std::mutex,吞吐明显提升。

TemPolor
TemPolor

AI音乐生成器,一键创作免版税音乐

下载
  • 读操作用 std::shared_lock<:shared_mutex></:shared_mutex>(RAII,自动 unlock_shared)
  • 写操作用 std::unique_lock<:shared_mutex></:shared_mutex>(等价于普通 std::unique_lock
  • 注意:Windows 上 VS2019+ 才完整支持;GCC 8+、Clang 7+ 支持较好;老标准库(如 libstdc++ 7)可能只提供 std::shared_timed_mutex,性能略差
  • 别为了“看起来高级”强行替换——写操作频繁时,shared_mutex 开销反而更大(内部状态更复杂)

std::condition_variable 等待必须配合 while 循环和 predicate

直接用 cv.wait(lock) 不带谓词,几乎总是错的。虚假唤醒(spurious wakeup)是 POSIX 和 C++ 标准明确允许的行为,线程可能在没人 notify 的情况下醒来,此时共享状态未必满足预期。

立即学习C++免费学习笔记(深入)”;

  • 永远用 cv.wait(lock, [&]{ return condition; }); 形式,让 wait 内部自动重检条件
  • 条件变量本身不保护数据——condition 表达式中访问的所有变量,必须由同一把锁保护(通常是同一个 std::mutex
  • notify_one() 只唤醒一个等待线程;notify_all() 唤醒全部——后者在竞争激烈时可能引发“惊群”,但比漏唤醒安全;选哪个取决于业务语义
  • 别在持有锁时做耗时操作(比如 I/O、复杂计算),否则阻塞其他线程;wait 唤醒后应尽快检查条件并释放锁

线程同步真正难的不是语法,而是状态建模:哪些变量会被谁改、在什么时机可见、失败路径是否破坏不变量。一个 std::atomic_flag 和三行内存序注释,有时比五层锁嵌套更可靠。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

105

2023.09.25

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

215

2023.09.15

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

192

2025.11.08

Python lambda详解
Python lambda详解

本专题整合了Python lambda函数相关教程,阅读下面的文章了解更多详细内容。

61

2026.01.05

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

764

2023.08.10

Java 并发编程高级实践
Java 并发编程高级实践

本专题深入讲解 Java 在高并发开发中的核心技术,涵盖线程模型、Thread 与 Runnable、Lock 与 synchronized、原子类、并发容器、线程池(Executor 框架)、阻塞队列、并发工具类(CountDownLatch、Semaphore)、以及高并发系统设计中的关键策略。通过实战案例帮助学习者全面掌握构建高性能并发应用的工程能力。

99

2025.12.01

function是什么
function是什么

function是函数的意思,是一段具有特定功能的可重复使用的代码块,是程序的基本组成单元之一,可以接受输入参数,执行特定的操作,并返回结果。本专题为大家提供function是什么的相关的文章、下载、课程内容,供大家免费下载体验。

498

2023.08.04

js函数function用法
js函数function用法

js函数function用法有:1、声明函数;2、调用函数;3、函数参数;4、函数返回值;5、匿名函数;6、函数作为参数;7、函数作用域;8、递归函数。本专题提供js函数function用法的相关文章内容,大家可以免费阅读。

166

2023.10.07

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

4

2026.03.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 11万人学习

C 教程
C 教程

共75课时 | 5.3万人学习

C++教程
C++教程

共115课时 | 21.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号