C++多线程编程:join与detach的致命陷阱

一、tha.jion 和 tha.deatch

1. 先讲两个函数的区别

tha.join();

  • 主线程等着子线程跑完,再继续往下走
  • 主线程会卡在这里,等子线程结束
  • 安全、不会出错

tha.detach();

  • 将子线程从主线程分离,主线程不再管理子线程,各自独立运行
  • 主线程继续往下跑,可能先跑完、直接退出程序
  • 子线程变成后台线程(守护线程),继续自己跑
  • 极容易出 bug!

2. 放到代码里,会发生什么灾难?

复制代码
Int a(10);
std::thread tha(funa, a);
tha.detach();  // 这里改成detach

// 主线程直接往下跑!不等子线程!
cout << "main---------------" << endl;
a.Print();
return 0;

结果 1:主线程可能先跑完,直接销毁 a

主线程退出 → 局部变量 a 被析构但子线程还在跑,还在使用已经被销毁的对象悬空对象、非法访问、程序直接崩溃!

结果 2:输出乱序

你会看到输出乱跳:

复制代码
main---------------
10
Creat Int:...
Copy Int:...

主线程先打印完了,子线程才开始跑。

结果 3:子线程还没跑完,程序已经结束

子线程直接被操作系统强行杀死

二、条件变量condition_variable

它就是 C++11 专门给线程用的 "等待 + 唤醒" 工具

1. 它到底是干嘛的?

一句话:让一个线程停下来等,直到另一个线程喊它,它才继续跑。

你可以把它理解成:

  • 线程 A:我等着,你弄好了叫我
  • 线程 B:我弄好了,喊你继续

这就是 condition_variable

2. 它必须配合谁一起用?

必须配合 std::mutex 互斥锁一起用不能单独用!

因为:

  • 等待的时候要解锁
  • 唤醒的时候要加锁条件变量自己不会锁,必须靠 mutex

3. 最核心的 3 个功能

  1. **wait()**线程停下来,阻塞等待→ 自动解锁 → 等着被唤醒

  2. notify_one() 唤醒一个正在等待的线程

  3. notify_all() 唤醒所有正在等待的线程

三、惊群现象

惊群现象 是指:使用 notify_all() 时,一次性唤醒所有等待线程,但只有一个线程能真正工作,其余线程白唤醒、白抢锁,造成 CPU 资源浪费。

在多线程轮流打印场景中:

  • notify_one 可能唤醒错误线程 → 死锁
  • notify_all 会产生惊群 → 但安全、不会死锁 所以必须用 notify_all

四、notify_one和notify_all

1.对比

notify_one()

  • 只唤醒1个正在 wait 的线程

  • 优点:无惊群,效率高

  • 缺点:可能唤醒 "错误线程" → 死锁

notify_all()

  • 唤醒所有正在 wait 的线程

  • 优点:绝对安全,不会死锁

  • 缺点:惊群效应,大量线程抢锁,浪费 CPU

2.什么时候用哪个?

用 notify_one 的场景:生产者消费者(一对多)

用 notify_all 的场景:多线程轮流打印 / 条件与线程绑定 / 程序退出

相关推荐
余额瞒着我当琳几秒前
C++--vector第二讲:手写 C++ STL:vector 源码剖析与迭代器失效分析
android·java·c++
郝学胜-神的一滴13 分钟前
[简化版 GAMES 104] 现代游戏引擎 06:从Tick时序到邮局模型,拆解确定性世界的底层密码
开发语言·c++·游戏引擎·图形渲染·软件开发·opengl
不会代码的小猴13 分钟前
6. Qt网络编程
开发语言·c++·笔记·qt·算法
沐风老师17 分钟前
从零开始学3dMax插件开发!
c++·3dmax插件·3dmax·maxscript
wuyk55511 小时前
98.C语言易混难点:字符数组与字符串指针的底层差异
c语言·开发语言·c++·stm32·嵌入式硬件·算法
峥无11 小时前
从0到1手撕红黑树:封装实现 my_map 与 my_set(SGI-STL 源码级深度解析)
开发语言·c++·笔记·算法·stl
波特率11520011 小时前
C++新特性---属性说明符与标准属性
开发语言·c++
不会代码的小猴12 小时前
3. 控件学习1
开发语言·c++·笔记·qt·算法
烧酒同学17 小时前
【C++】记录size of std::vector的巧妙坑
开发语言·c++·图形渲染
@呱呱爱学习19 小时前
C++大成之路_ STL容器_ Vector
开发语言·c++