背景
在 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 的入口函数中参数通过隐式类型转换产生临时对象时,临时对象的构造是在子线程中执行的,如下图:
可以通过显示的调用构造函数来生成临时对象,来强制使类型转换在主线程中执行,如下图: