菜鸟笔记
提升您的技术认知

std::thread 传递参数

背景

在 C++ 中使用一个可调用对象构造一个 std::thread 对象,即可创建一个线程。在创建 thread 对象以后,要在随后的某个地方显式地调用 join 或 detach 以便让 std::thread 处于不可联结状态。

std::thread 传递参数

①.传递简单数据类型
std::thread 的入口函数中传递简单类型数据,如 int 等,本质上是值传递,可以放心的 detach,如下图:

如上如图,虽然是引用接受参数,但线程中参数的地址和主线程中参数地址却不一样,是拷贝了一个新的参数。
②.传递指针
std::thread 的入口函数中传递指针时,要小心使用 detach,如下图:

如上图,线程函数中参数首地址和形参首地址一样,要避免使用 detach()。
③.传递类对象
std::thread 的入口函数中传递类对象时,本质上也是传递的类对象的拷贝。

#include "thread"
#include "iostream"
using namespace std;
class demoClass
{
  
public:
  demoClass(int var) :m_var(var)
  {
  
    cout << "构造函数执行,线程id:" << this_thread::get_id() << endl;
  }
  demoClass(const demoClass& demo) :m_var(demo.m_var)
  {
  
    cout << "拷贝构造函数执行,线程id:" << this_thread::get_id() << endl;
  }
  ~demoClass()
  {
  
    cout << "析构函数执行,线程id:" << this_thread::get_id() << endl;
  }
private:
  int m_var;
};

void functionToThread(const demoClass & demo)
{
  
  cout << "线程启动......" << endl;
  cout << "线程id:" << this_thread::get_id() << " demo 的地址 "<< &demo << endl;
  cout << "线程结束......" << endl;
}
int main()
{
  
  demoClass demo(20);
  cout << "线程id:" << this_thread::get_id() << " demo 的地址 " << &demo << endl;

  thread myThread(functionToThread, demo);

  myThread.join();

  cout << "主线程结束......" << endl;
  system("pause");
    return 0;
}

执行结果如下:虽然是引用接受参数,但主线程中参数对象的地址和传入子线程中对象地址不一样:

④.传递类对象的引用
使用 std::ref() 传递对象,则传递的时真引用,如下图:

⑤.传递临时对象
当 std::thread 的入口函数中参数通过隐式类型转换产生临时对象时,临时对象的构造是在子线程中执行的,如下图:

可以通过显示的调用构造函数来生成临时对象,来强制使类型转换在主线程中执行,如下图: