(二)C++线程管理

0 阅读4分钟

std::thread 基础用法

1.std::thread 简介 std::thread 是C++11标准库中提供的线程类,用于创建和管理线程。它是现代C++多线程编程的基础,参考:cppreference.cn/w/cpp/threa…

2.基本线程创建

  • std::thread 的构造函数,用来传入需要子线程执行的操作。
  • joinable()  返回一个布尔值,表示线程对象是否关联着一个可被 join/detach 的活动线程。
  • join()  阻塞当前线程,直到被 join 的线程执行完毕。

image.png

运行结果如下:

image.png

3.重点:std::thread类对象构造完毕之后,就已经处于就绪状态了,一旦系统调度器给它分配资源,它就会立即开始运行。理论上你可以认为,构造和开始运行是同时开始的。

线程创建与生命周期管理

std::stread其实就是构造的时候传入一个被执行的方法,然后就会在子线程中执行这个方法直到这个方法结束,这个方法不仅仅是函数,可以有很多形式:

  • 静态函数

  • 成员函数

  • lambda表达式

  • 函数对象

  • 使用std::bind

join() 与 detach() 的区别

  • join():主线程等待子线程完成,保持关联,同步执行

  • detach():主线程不等待子线程,完全分离,异步执行

image.png

image.png

image.png

[豆包:] 🎯 主人,我用大白话给你讲明白  std::bind !

一句话总结: std::bind  就是给函数「打包」,把函数和它要用的参数、对象绑在一起,变成一个可以直接调用的「成品函数」。

 

一、先搞懂:你代码里为啥要用它?

你要在线程里跑一个类的成员函数,比如  ThreadManager  里的  member_function 。 成员函数有个「小脾气」:它必须知道自己是属于哪个对象的(也就是  this  指针),不然没法干活。

但  std::thread  线程只认「直接能调用的函数」,不认带  this  的成员函数。 这时候  std::bind  就来当「中间人」了:

我帮你把「成员函数 + 对应的对象 + 要传的参数」打包成一个完整的、能直接调用的函数,线程直接用这个打包好的就行!

 

二、举个生活例子,一秒懂

你要让外卖员(线程)给你送奶茶:

  • 「点奶茶」这个动作 = 类的成员函数(必须知道给谁点,也就是对象)
  • 「你」 = 类的对象实例( &manager )
  • 「三分糖、少冰」 = 函数参数( 5 )

外卖员(线程)只知道「送奶茶」,不知道给谁送、要什么口味。  std::bind  就相当于:

把「给XX点三分糖少冰的奶茶」这个完整指令打包好,给外卖员。 外卖员拿到这个指令,直接执行就行,不用再问「给谁点?要啥口味?」

 

三、对应到你代码里,就是这回事

cpp

// 1. 打包:把「成员函数 + 对象 + 参数」绑成一个新函数 auto bound_func = std::bind(&ThreadManager::member_function, &manager, 5); // 2. 线程直接用这个打包好的函数 std::thread t5(bound_func);  

  • 打包前: member_function  是个半成品,必须给它对象和参数才能用
  • 打包后: bound_func  是个成品,直接调用  bound_func()  就等于  manager.member_function(5) 
  • 线程拿到  bound_func ,直接跑就行,啥都不用管

 

四、 std::bind  还能干嘛?(超简单版)

除了打包成员函数,它还有两个常用小功能:

1. 提前填好部分参数

比如一个函数要两个数相加,你可以用  bind  把第一个数固定成10,之后只需要传第二个数就行。

2. 换参数顺序

比如函数是  print(a, b) ,你可以用  bind  让它变成  print(b, a) ,调用的时候自动换顺序。

 

五、现在更简单的替代方案(不用记bind语法)

现在C++里,用lambda表达式比  std::bind  更直白,一眼就能看懂:

cpp

// 直接用lambda把成员函数包起来,效果和bind完全一样

std::thread t5( {
    manager.member_function(5);
});

 

意思就是:线程执行这个lambda,lambda里直接调用对象的成员函数,不用绕弯子。

 

六、一句话收尾

 std::bind  就是个函数打包工具,专门解决「成员函数没法直接给线程用」的问题,把半成品函数变成成品,让线程能直接跑。