一.线程的初始化参数需要注意以下几个问题:
1.回调函数使用引用参数接收值时,必须声明为const,否则报错;(线程基于数据安全保护的考虑)
2.回调函数必须声明为指针,才能修改实参;
3.对象隐式转换是在子线程中进行的;
4.回调函数参数为非引用时,对象的拷贝是在子线程中进行的;
二.使用detach需要注意的问题
由上四点可以发现,使用detach需要注意的问题:
1.传递对象时,建议用引用的方式进行值传递;
2.利用explicit使类不支持隐式转换;
三.数据的修改方法:
1.我们提到线程基于数据安全保护的考虑,回调函数使用引用参数接收值时,必须声明为const,否则报错;如果我们需要通过引用去传递对象时,需要用到一个函数std::ref();
2.指针传递和共享指针传递;
1.回调函数使用引用参数接收值时,必须声明为const,否则报错;(线程基于数据安全保护的考虑)
void func(const string &str) //必须声明为const
{
cout << "func函数," << "线程id=" << std::this_thread::get_id() << ",string=" << str << endl;
}
int main()`在这里插入代码片`
{
cout<< "main函数," << "线程id=" << std::this_thread::get_id() << endl;
string s("hello world!");
thread th(func, s); //对象拷贝传递
th.join();
return 0;
}
2.回调函数必须声明为指针,才能修改实参;
#include
#include
using namespace std;
class Test
{
public:
Test(int a):a_m(a)
{
cout << "调用Test构造函数," << "线程id:" << std::this_thread::get_id() << endl;
}
~Test()
{
cout << "调用Test析构函数," << "线程id:" << std::this_thread::get_id() << endl;
}
private:
int a_m;
};
void func(Test* test)
{
cout << "func函数," << "线程id:" << std::this_thread::get_id() << endl;
}
int main()
{
cout << "main函数," << "主线程id:" << std::this_thread::get_id() << endl;
Test test(10);
thread th(func, &test);//用隐式类型转化的方式
th.join();
return 0;
}
//打印结果
root@epc:/home/share/test# ./test
main函数,主线程id:140712058914624
调用Test构造函数,线程id:140712058914624
func函数,线程id:140712041473792
调用Test析构函数,线程id:140712058914624
root@epc:/home/share/test#
3.对象隐式转换是在子线程中进行的;
#include
#include
using namespace std;
class Test
{
public:
Test(int a):a_m(a)
{
cout << "调用Test构造函数," << "线程id:" << std::this_thread::get_id() << endl;
}
~Test()
{
cout << "调用Test析构函数," << "线程id:" << std::this_thread::get_id() << endl;
}
private:
int a_m;
};
void func(const Test& test)
{
cout << "func函数," << "线程id:" << std::this_thread::get_id() << endl;
}
int main()
{
cout << "main函数," << "主线程id:" << std::this_thread::get_id() << endl;
thread th(func, 10);//用隐式类型转化的方式
th.join();
return 0;
}
//打印结果
root@epc:/home/share/test# ./test
main函数,主线程id:139788677470016
调用Test构造函数,线程id:139788660029184
func函数,线程id:139788660029184
调用Test析构函数,线程id:139788660029184
root@epc:/home/share/test#
4.回调函数参数为非引用时,对象的拷贝是在子线程中进行的;
#include
#include
using namespace std;
class Test
{
public:
Test(int a):a_m(a)
{
cout << "调用Test构造函数," << "线程id:" << std::this_thread::get_id() << endl;
}
Test(const Test &a)
{
cout << "调用Test拷贝构造函数," << "线程id:" << std::this_thread::get_id() << endl;
}
~Test()
{
cout << "调用Test析构函数," << "线程id:" << std::this_thread::get_id() << endl;
}
private:
int a_m;
};
void func(Test test) //注意此处非引用
{
cout << "func函数," << "线程id:" << std::this_thread::get_id() << endl;
}
int main()
{
cout << "main函数," << "主线程id:" << std::this_thread::get_id() << endl;
Test test(10);
thread th(func, test);//用隐式类型转化的方式
th.join();
return 0;
}
//打印结果
root@epc:/home/share/test# ./test
main函数,主线程id:140565759584064
调用Test构造函数,线程id:140565759584064
调用Test拷贝构造函数,线程id:140565759584064
调用Test拷贝构造函数,线程id:140565759584064
调用Test析构函数,线程id:140565759584064
调用Test拷贝构造函数,线程id:140565742143232 //在子线程进行了拷贝构造函数;
func函数,线程id:140565742143232
调用Test析构函数,线程id:140565742143232
调用Test析构函数,线程id:140565742143232
调用Test析构函数,线程id:140565759584064
root@epc:/home/share/test#
``
1.我们提到线程基于数据安全保护的考虑,回调函数使用引用参数接收值时,必须声明为const,否则报错;如果我们需要通过引用去传递对象时,需要用到一个函数std::ref();
#include
#include
using namespace std;
class Test
{
public:
explicit Test(int a):a_m(a)
{
cout << "调用Test构造函数," << "线程id:" << std::this_thread::get_id() << endl;
}
~Test()
{
cout << "调用Test析构函数," << "线程id:" << std::this_thread::get_id() << endl;
}
void set(int a){a_m = a;}
int get(){return a_m;}
private:
int a_m;
};
void func(Test& test)
{
cout << "func函数," << "线程id:" << std::this_thread::get_id() << endl;
test.set(100);
}
int main()
{
cout << "main函数," << "主线程id:" << std::this_thread::get_id() << endl;
Test test(10);
cout << "子线程执行前test.a_m=" << test.get() << endl;
thread th(func, ref(test));//用隐式类型转化的方式
th.join();
cout << "子线程执行后test.a_m=" << test.get() << endl;
return 0;
}
//打印结果
root@epc:/home/share/test# ./test
main函数,主线程id:140471238637376
调用Test构造函数,线程id:140471238637376
子线程执行前test.a_m=10
func函数,线程id:140471221196544
子线程执行后test.a_m=100
调用Test析构函数,线程id:140471238637376
root@epc:/home/share/test#
2.指针传递和共享指针传递;
#include
#include
#include
using namespace std;
class Test
{
public:
explicit Test(int a):a_m(a)
{
cout << "调用Test构造函数," << "线程id:" << std::this_thread::get_id() << endl;
}
~Test()
{
cout << "调用Test析构函数," << "线程id:" << std::this_thread::get_id() << endl;
}
void set(int a){a_m = a;}
int get(){return a_m;}
private:
int a_m;
};
void func(shared_ptr ptr)
{
cout << "func函数," << "线程id:" << std::this_thread::get_id() << endl;
ptr->set(100);
}
int main()
{
cout << "main函数," << "主线程id:" << std::this_thread::get_id() << endl;
shared_ptr test_ptr(new Test(10));
cout << "子线程执行前test.a_m=" << test_ptr->get() << endl;
thread th(func, test_ptr);
th.join();
cout << "子线程执行后test.a_m=" << test_ptr->get() << endl;
return 0;
}
//打印结果
root@epc:/home/share/test# ./test
main函数,主线程id:140623717164864
调用Test构造函数,线程id:140623717164864
子线程执行前test.a_m=10
func函数,线程id:140623699724032
子线程执行后test.a_m=100
调用Test析构函数,线程id:140623717164864
root@epc:/home/share/test#