0

0

c++如何实现多线程编程_c++中thread库基本用法【进阶】

冰火之心

冰火之心

发布时间:2026-03-15 21:04:03

|

339人浏览过

|

来源于php中文网

原创

std::thread 构造后必须 join 或 detach,否则析构时调用 std::terminate() 导致程序崩溃,错误信息如“Resource deadlock avoided”或“terminate called without an active exception”。

c++如何实现多线程编程_c++中thread库基本用法【进阶】

std::thread 构造后必须 join 或 detach

不处理的 std::thread 对象在析构时会调用 std::terminate(),程序直接崩溃,错误信息是 std::thread::~thread(): Resource deadlock avoided 或更常见的 terminate called without an active exception

常见错误是写完 std::thread t{func} 就结束作用域,没管它:

void bad_example() {
    std::thread t([]{ std::cout << "hello\n"; });
} // t 析构 → crash
  • t.join() 等待线程结束(适合需要同步结果的场景)
  • t.detach() 让线程后台运行(之后不能再控制或等待,且需确保所捕获变量生命周期足够长)
  • 更安全的做法:把 std::thread 包进 RAII 类型里,比如封装成 scoped_thread,或直接用 std::jthread(C++20,构造时自动 join)

传参到 thread 时要小心值传递和引用传递

std::thread 的参数默认按值拷贝,即使你写了 &x,也会被当作右值转发,导致意外的拷贝或绑定失效。

比如想在线程里修改外部变量 int a = 0

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

int a = 0;
std::thread t([&a]{ a = 42; }); // ✅ 正确:lambda 捕获引用
// 但下面这句不行:
std::thread t2(func, a);         // ❌ func 收到的是 a 的副本
std::thread t3(func, std::ref(a)); // ✅ 用 std::ref 包装才传引用
  • 函数对象参数一律按值移动/拷贝,不会自动推导引用语义
  • 要传引用,必须显式用 std::ref(x)std::cref(x)
  • 传入局部变量地址(如 &local_var)而没保证生命周期,detach 后极易访问野指针

共享数据不加锁就会出现未定义行为

多个线程读写同一变量(哪怕只是 counter++),只要没同步机制,就是未定义行为——不是“偶尔错”,而是编译器可任意优化、CPU 可乱序执行、结果完全不可预测。

B12
B12

B12是一个由AI驱动的一体化网站建设平台

下载

典型现象:循环 10000 次,两个线程各加 1,最后 counter 却远小于 20000。

  • 基础方案:用 std::mutex + std::lock_guard 保护临界区
  • 简单计数可用 std::atomic<int></int>,比锁轻量,但注意 ++ 是原子的,而 a = a + 1 不是
  • 别用 volatile 替代同步——它只禁用编译器优化,不管 CPU 重排也不提供原子性

thread_local 变量每个线程一份,但初始化时机容易误判

thread_local 看似简单,实际行为依赖线程启动时机和变量定义位置。

全局或命名空间作用域的 thread_local 变量,在**首次访问该线程中该变量时**初始化;函数内定义的,则每次进入函数都可能触发(如果该线程还没初始化过)。

  • 不能假设所有线程的 thread_local 变量在 main() 开始就已构造好
  • 若初始化过程抛异常,该线程后续访问会再次尝试初始化(可能反复失败)
  • 销毁顺序不确定,跨线程使用其地址做回调时,要确认目标线程还没退出

多线程下最麻烦的从来不是怎么开线程,而是变量谁在什么时候构造、谁在什么时候消亡、谁还拿着指向它的指针。这些细节一漏,问题就藏得深、复现难。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
resource是什么文件
resource是什么文件

Resource文件是一种特殊类型的文件,它通常用于存储应用程序或操作系统中的各种资源信息。它们在应用程序开发中起着关键作用,并在跨平台开发和国际化方面提供支持。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

183

2023.12.20

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1051

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

617

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

335

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

235

2025.08.29

c++中volatile关键字的作用
c++中volatile关键字的作用

本专题整合了c++中volatile关键字的相关内容,阅读专题下面的文章了解更多详细内容。

76

2025.10.23

c++中volatile关键字的作用
c++中volatile关键字的作用

本专题整合了c++中volatile关键字的相关内容,阅读专题下面的文章了解更多详细内容。

76

2025.10.23

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

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

786

2023.08.10

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

69

2026.03.13

热门下载

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

精品课程

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

共94课时 | 11.4万人学习

C 教程
C 教程

共75课时 | 5.5万人学习

C++教程
C++教程

共115课时 | 22.1万人学习

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

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