从前面的知识我们知道,
thread mythread(mythreadmethod);
void mythreadmethod() {
cout << "mythreadmethod start..." << endl;
cout << "mythreadmethod end..." << endl;
}
int main()
{
thread mythread(mythreadmethod);
mythread.join();
}
Teacher141 t1;
thread mythread1(t1);
Teacher141 t2;
thread mythread12(t2,20);
//创建线程的方法,使用operator()函数做为 线程的入口函数
class Teacher141 {
public:
void operator()() {
cout << "Teacher141 的 operator() 没有参数的方法被调用" << endl;
}
void operator()(int num ) {
cout << "Teacher141 的 operator(int num) 的方法被调用: num = " << num << endl;
}
int m_age;
};
//operator()()做thread 启动方法入口
void main() {
cout << " test thread start " << endl;
//operator()()做thread 启动参数
Teacher141 t1;
thread mythread1(t1);
//operator()(T t)做thread 启动参数
Teacher141 t2;
thread mythread12(t2,20);
mythread1.join();
mythread12.join();
cout << " test thread end " << endl;
}
Teacher142 tea;
thread mythread(&Teacher142::writeTeacherName,&tea);
//类的成员函数做 线程启动函数入口
class Teacher142 {
public:
void writeTeacherName() {
for (int i = 0; i < 1000; i++) {
cout << " 子线程id 为 : " << this_thread::get_id() << " i = " << i << endl;
}
}
};
void main() {
Teacher142 tea;
thread mythread(&Teacher142::writeTeacherName,&tea);
for (int i = 0; i < 1000;i++) {
cout << "主线程id 为 : " << this_thread::get_id() << " i = " << i << endl;
}
mythread.join();
}
void main() {
std::cout << "Hello World0 start!\n";
auto mylambdathread = []() {
cout << "mylambdathread start..." << endl;
cout << "mylambdathread end..." << endl;
};
thread mythread(mylambdathread);
mythread.join();
}
从前面的知识点,我们已经掌握了可以从主线程 启动 新线程了。但是没有传递参数。
这一节,我们看怎么传递参数。
实参和传递过来的地址值是不同的
void fun143(int num) {
//num 的值 : 0x00000093fa6ff580 {200}
for (int i = 0; i < 10;i++) {
cout << "子线程 id为 = " << this_thread::get_id() << " i = " << i << " fun143 num = " << num << endl;
}
}
void main() {
//传递普通类型: int num ,非引用
int a = 200;//0x00000093fa30f724 {200}
thread mythread(fun143,a);
for (int i = 0; i < 10;i++) {
cout << " 主线程 id 为 " << this_thread::get_id()<< " i = " << i << endl;
}
mythread.join();
}
实参和传递过来的地址值是不同的
void fun144(string str) {
for (int i = 0; i < 10; i++) {
//子线程 id为 = 2976 i = 0 fun144 str = nihao & str 0000004C06EFF578
cout << "子线程 id为 = " << this_thread::get_id() << " i = " << i << " fun144 str = " << str << " &str " << &str << endl;
}
}
//传递C++自带类型: string str ,非引用
void main() {
string strsource ("nihao");
cout << "主线程 id 为 " << this_thread::get_id() << " strsource = " << strsource << " &strsource = " << &strsource << endl;
//主线程 id 为 17956 strsource = nihao & strsource = 0000004C06B5F928
thread mythread(fun144, strsource);
for (int i = 0; i < 10; i++) {
cout << " 主线程 id 为 " << this_thread::get_id() << " i = " << i << endl;
}
mythread.join();
}
copy 构造函数被调用了2次,这至少说明thread 类内部肯定做了很多事情
class Teacher145 {
public:
Teacher145(int age) :mage(age) {
cout << "Teacher145 构造函数 mage = " << mage << " this_thread::getid()" << this_thread::get_id()<< " this " << this<< endl;
}
Teacher145(const Teacher145& obj) {
this->mage = obj.mage;
cout << "Teacher145 copy 构造函数" << " this_thread::getid() = " << this_thread::get_id() << " this = " << this <<" &obj = " << &obj << endl;
}
~Teacher145() {
cout << "Teacher145 析构函数被调用" << " this_thread::getid() = " << this_thread::get_id() << endl;
}
private:
int mage;
public:
int getAge() {
return this->mage;
}
};
void fun145(Teacher145 temptea) {
cout << "子线程 this_thread::get_id() = " << this_thread::get_id() << " &temptea = " << &temptea << " temptea.getAge() = " << temptea.getAge() << endl;
for (int i = 0; i < 10; ++i) {
cout << "子线程 this_thread::get_id() = " << this_thread::get_id() << " iii = " << i << endl;
}
}
void main() {
Teacher145 tea(20);
cout << "主线程 this_thread::get_id() = " << this_thread::get_id() << " &tea = " << &tea << " tea.getAge() = " << tea.getAge()<
class Teacher150 {
public:
Teacher150(int age) :mage(age) {
cout << "Teacher150 构造函数 mage = " << mage << " this_thread::getid()" << this_thread::get_id() << " this " << this << endl;
}
Teacher150(const Teacher150& obj) {
this->mage = obj.mage;
cout << "Teacher150 copy 构造函数" << " this_thread::getid() = " << this_thread::get_id() << " this = " << this << " &obj = " << &obj << endl;
}
~Teacher150() {
cout << "Teacher150 析构函数被调用" << " this_thread::getid() = " << this_thread::get_id() << endl;
}
private:
int mage;
public:
int getAge() {
return this->mage;
}
void setAge(int age) {
this->mage = age;
}
};
void func150(const Teacher150 & temptea) {
cout << "子线程id = " << this_thread::get_id() << " &temptea = " << &temptea << endl;
}
void main150() {
//传递 自定义 类的引用
Teacher150 tea(200);
cout << "主线程id = " << this_thread::get_id() << " &tea = " << &tea << endl;
thread mythread(func150,tea);
mythread.join();
//Teacher150 构造函数 mage = 200 this_thread::getid()15860 this 000000C1B95DFB14
// 主线程id = 15860 & tea = 000000C1B95DFB14
// Teacher150 copy 构造函数 this_thread::getid() = 15860 this = 0000021FCA5C2520 &obj = 000000C1B95DFB14
// 子线程id = 8600 & temptea = 0000021FCA5C2520
// Teacher150 析构函数被调用 this_thread::getid() = 8600
// Teacher150 析构函数被调用 this_thread::getid() = 15860
}
class Teacher150 {
public:
Teacher150(int age) :mage(age) {
cout << "Teacher150 构造函数 mage = " << mage << " this_thread::getid()" << this_thread::get_id() << " this " << this << endl;
}
Teacher150(const Teacher150& obj) {
this->mage = obj.mage;
cout << "Teacher150 copy 构造函数" << " this_thread::getid() = " << this_thread::get_id() << " this = " << this << " &obj = " << &obj << endl;
}
~Teacher150() {
cout << "Teacher150 析构函数被调用" << " this_thread::getid() = " << this_thread::get_id() << endl;
}
private:
int mage;
public:
int getAge() {
return this->mage;
}
void setAge(int age) {
this->mage = age;
}
};
void func151( Teacher150 & temptea) {
cout << "子线程id = " << this_thread::get_id() << " &temptea = " << &temptea << endl;
temptea.setAge(89);
}
void main() {
//传递 自定义 类的引用
Teacher150 tea(200);
cout << "主线程id = " << this_thread::get_id() << " &tea = " << &tea << endl;
thread mythread(func151, ref(tea));
mythread.join();
cout << "tea.age = " << tea.getAge() << endl;
//Teacher150 构造函数 mage = 200 this_thread::getid()18644 this 000000109D95F6F4
// 主线程id = 18644 & tea = 000000109D95F6F4
// 子线程id = 11016 & temptea = 000000109D95F6F4
// tea.age = 89
// Teacher150 析构函数被调用 this_thread::getid() = 18644
}
class Teacher161 {
public:
Teacher161(int age) :mage(age) {
cout << "Teacher161 构造函数 mage = " << mage << " this_thread::getid()" << this_thread::get_id() << " this " << this << endl;
}
Teacher161(const Teacher161& obj) {
this->mage = obj.mage;
cout << "Teacher161 copy 构造函数" << " this_thread::getid() = " << this_thread::get_id() << " this = " << this << " &obj = " << &obj << endl;
}
~Teacher161() {
cout << "Teacher161 析构函数被调用" << " this_thread::getid() = " << this_thread::get_id() << endl;
}
private:
int mage;
public:
int getAge() {
return this->mage;
}
void setAge(int age) {
this->mage = age;
}
};
class Teacher160 {
public:
void fun143(int num) {
for (int i = 0; i < 10; i++) {
cout << "子线程 id为 = " << this_thread::get_id() << " i = " << i << " fun143 num = " << num << " & num = " << &num << endl;
}
}
void fun144(string str) {
for (int i = 0; i < 10; i++) {
cout << "子线程 id为 = " << this_thread::get_id() << " i = " << i << " fun144 str = " << str << " &str " << &str << endl;
}
}
void fun145(Teacher161 temptea) {
cout << "子线程 this_thread::get_id() = " << this_thread::get_id() << " &temptea = " << &temptea << " temptea.getAge() = " << temptea.getAge() << endl;
for (int i = 0; i < 10; ++i) {
cout << "子线程 this_thread::get_id() = " << this_thread::get_id() << " iii = " << i << endl;
}
}
void fun146(const int &num) {//注意,这里要使用const 标识
for (int i = 0; i < 10; i++) {
cout << "子线程 id为 = " << this_thread::get_id() << " i = " << i << " fun146 num = " << num << " &num = " << &num << endl;
}
}
void fun147(int &num) {//注意,这里没有加 const 标识
//num 的值 :=
for (int i = 0; i < 10; i++) {
cout << "子线程 id为 = " << this_thread::get_id() << " i = " << i << " fun147 num = " << num << " &num = " << &num << endl;
}
}
void fun148(const string &str) {//注意,这里要使用const 标识
//num 的值 :=
for (int i = 0; i < 10; i++) {
cout << "子线程 id为 = " << this_thread::get_id() << " i = " << i << " fun148 string = " << str << " &str = " << &str << endl;
}
}
void fun149(string &str) {
cout << "子线程 id为 = " << this_thread::get_id() << " fun149 string = " << str << " &str = " << &str << endl;
str = "str content changed";
}
void func150(const Teacher161 & temptea) {
cout << "子线程id = " << this_thread::get_id() << " &temptea = " << &temptea << endl;
}
void func151(Teacher161 & temptea) {
cout << "子线程id = " << this_thread::get_id() << " &temptea = " << &temptea << endl;
temptea.setAge(89);
}
public:
Teacher160() {
cout << "Teacher160 构造函数" << endl;
}
Teacher160(int age) :m_age(age) {
cout << "Teacher160 构造函数 int 执行" << endl;
}
Teacher160(const Teacher160& obj) {
this->m_age = obj.m_age;
cout << "Teacher160 copy 构造函数" << endl;
}
~Teacher160() {
cout << "Teacher160 析构函数" << endl;
}
private:
int m_age;
public:
void setTeacher160age(int age) {
this->m_age = age;
}
int getTeacher160age() {
return this->m_age;
}
};
void main(){
Teacher160 tea;
int num = 10;
cout << "主线程 " << this_thread::get_id() << " num = " << num << " &num = " <<&num << endl;
thread mythread(&Teacher160::fun143, &tea,num);
mythread.join();
// Teacher160 构造函数
// 主线程 16888 num = 10 & num = 0000001D49DBFAD4
// 子线程 id为 = 15876 i = 0 fun143 num = 10 & num = 0000001D4A0FF4E8
// 子线程 id为 = 15876 i = 1 fun143 num = 10 & num = 0000001D4A0FF4E8
// 子线程 id为 = 15876 i = 2 fun143 num = 10 & num = 0000001D4A0FF4E8
// 子线程 id为 = 15876 i = 3 fun143 num = 10 & num = 0000001D4A0FF4E8
// 子线程 id为 = 15876 i = 4 fun143 num = 10 & num = 0000001D4A0FF4E8
// 子线程 id为 = 15876 i = 5 fun143 num = 10 & num = 0000001D4A0FF4E8
// 子线程 id为 = 15876 i = 6 fun143 num = 10 & num = 0000001D4A0FF4E8
// 子线程 id为 = 15876 i = 7 fun143 num = 10 & num = 0000001D4A0FF4E8
// 子线程 id为 = 15876 i = 8 fun143 num = 10 & num = 0000001D4A0FF4E8
// 子线程 id为 = 15876 i = 9 fun143 num = 10 & num = 0000001D4A0FF4E8
// Teacher160 析构函数
}
Teacher160 tea;
string strsource("haoheiyou");
cout << "主线程 " << this_thread::get_id() << " strsource = " << strsource << " &strsource = " << &strsource << endl;
thread mythread(&Teacher160::fun144, &tea, strsource);
mythread.join();
//Teacher160 构造函数
// 主线程 16348 strsource = haoheiyou & strsource = 000000351C34F8A8
// 子线程 id为 = 13932 i = 0 fun144 str = haoheiyou & str 000000351C6FF438
// 子线程 id为 = 13932 i = 1 fun144 str = haoheiyou & str 000000351C6FF438
// 子线程 id为 = 13932 i = 2 fun144 str = haoheiyou & str 000000351C6FF438
// 子线程 id为 = 13932 i = 3 fun144 str = haoheiyou & str 000000351C6FF438
// 子线程 id为 = 13932 i = 4 fun144 str = haoheiyou & str 000000351C6FF438
// 子线程 id为 = 13932 i = 5 fun144 str = haoheiyou & str 000000351C6FF438
// 子线程 id为 = 13932 i = 6 fun144 str = haoheiyou & str 000000351C6FF438
// 子线程 id为 = 13932 i = 7 fun144 str = haoheiyou & str 000000351C6FF438
// 子线程 id为 = 13932 i = 8 fun144 str = haoheiyou & str 000000351C6FF438
// 子线程 id为 = 13932 i = 9 fun144 str = haoheiyou & str 000000351C6FF438
// Teacher160 析构函数
Teacher160 tea;
Teacher161 tea161(61);
cout << "主线程 " << this_thread::get_id() << " tea161 = " << &tea161 << endl;
thread mythread2(&Teacher160::fun145,tea, tea161);
mythread2.join();
//结果是Teacher161 的构造函数调用一次,copy 构造调用函数调用2次。析构了3次
//Teacher160 构造函数
// Teacher161 构造函数 mage = 61 this_thread::getid()19132 this 000000E5C099FC04
// 主线程 19132 tea161 = 000000E5C099FC04
// Teacher161 copy 构造函数 this_thread::getid() = 19132 this = 0000029CFC121E90 &obj = 000000E5C099FC04
// Teacher160 copy 构造函数
// Teacher161 copy 构造函数 this_thread::getid() = 16280 this = 000000E5C0CFF0E4 &obj = 0000029CFC121E90
// 子线程 this_thread::get_id() = 16280 & temptea = 000000E5C0CFF0E4 temptea.getAge() = 61
// 子线程 this_thread::get_id() = 16280 iii = 0
// 子线程 this_thread::get_id() = 16280 iii = 1
// 子线程 this_thread::get_id() = 16280 iii = 2
// 子线程 this_thread::get_id() = 16280 iii = 3
// 子线程 this_thread::get_id() = 16280 iii = 4
// 子线程 this_thread::get_id() = 16280 iii = 5
// 子线程 this_thread::get_id() = 16280 iii = 6
// 子线程 this_thread::get_id() = 16280 iii = 7
// 子线程 this_thread::get_id() = 16280 iii = 8
// 子线程 this_thread::get_id() = 16280 iii = 9
// Teacher161 析构函数被调用 this_thread::getid() = 16280
// Teacher160 析构函数
// Teacher161 析构函数被调用 this_thread::getid() = 16280
// Teacher161 析构函数被调用 this_thread::getid() = 19132
// Teacher160 析构函数
Teacher160 tea;
int num = 60;
cout << "主线程 " << this_thread::get_id() << " num = " << &num << endl;
thread mythread2(&Teacher160::fun146, &tea, num);
mythread2.join();
//Teacher160 构造函数
// 主线程 11392 num = 00000085E5F0F4C4
// 子线程 id为 = 17400 i = 0 fun146 num = 60 & num = 000002453746A6D0
这两个地址是一样的,因此,改一个,另一个也会变。
Teacher160 tea;
int num = 60;
cout << "主线程 " << this_thread::get_id() << " num = " << &num << endl;
thread mythread2(&Teacher160::fun147, &tea, ref(num));
mythread2.join();
cout<<"num = "<< num << endl;
//Teacher160 构造函数
// 主线程 14780 num = 00000001000FFBE4
// 子线程 id为 = 18540 fun147 num = 60 & num = 00000001000FFBE4
// num = 888
// Teacher160 析构函数
Teacher160 tea;
string strscource("www.baidu.com");
cout << "主线程 " << this_thread::get_id() << " &strscource = " << &strscource << " strscource = " << strscource << endl;
thread mythread2(&Teacher160::fun148, &tea, strscource);
mythread2.join();
//主线程 16668 & strscource = 00000083DBD4F8D8 strscource = www.baidu.com
// 子线程 id为 = 12156 i = 0 fun148 string = www.baidu.com &str = 000001A5BA056200
Teacher160 tea;
string strscource("www.baidu.com");
cout << "主线程 " << this_thread::get_id() << " &strscource = " << &strscource << " strscource = " << strscource << endl;
thread mythread2(&Teacher160::fun149, &tea, ref(strscource));
mythread2.join();
cout << "strscource = " << strscource << endl;
结果:
Teacher160 构造函数
主线程 15976 &strscource = 000000DF866FFBB8 strscource = www.baidu.com
子线程 id为 = 16528 fun149 string = www.baidu.com &str = 000000DF866FFBB8
strscource = str content changed
Teacher160 析构函数
Teacher160 tea;
Teacher161 tea161(81);
cout << "主线程 " << this_thread::get_id() << " tea161 = " << &tea161 << endl;
thread mythread2(&Teacher160::func150, &tea, tea161);
mythread2.join();
//即使使用了引用,Teacher161调用了构造函数,Teacher161还调用了 copy 构造函数,实际参数和形参依然不是一个地址
//Teacher160 构造函数
// Teacher161 构造函数 mage = 81 this_thread::getid()16348 this 000000816273F9E4
// 主线程 16348 tea161 = 000000816273F9E4
// Teacher161 copy 构造函数 this_thread::getid() = 16348 this = 000002797B7AA6D0 &obj = 000000816273F9E4
// 子线程id = 15848 & temptea = 000002797B7AA6D0
// Teacher161 析构函数被调用 this_thread::getid() = 15848
// Teacher161 析构函数被调用 this_thread::getid() = 16348
// Teacher160 析构函数
使用了ref,传递的实参和形参就是一个了
Teacher160 tea;
Teacher161 tea161(91);
cout << "主线程 " << this_thread::get_id() << " tea161 = " << &tea161 << endl;
thread mythread2(&Teacher160::func151, &tea, ref(tea161));
mythread2.join();
cout << tea161.getAge()<
unique_ptr,注意要用move
class Teacher162 {
public:
void funptr(unique_ptr ptr) {
cout << "子线程 id为 = " << this_thread::get_id() << " funptr *ptr = " << *ptr << " ptr = " << ptr << endl;
}
};
void main(){
///智能指针
Teacher162 tea;
unique_ptr ptr(new int(20));
cout << "子线程的id = " << this_thread::get_id()<< " *ptr = " <<*ptr <<" ptr = " << ptr<< endl;
thread mythread(&Teacher162::funptr,tea,move(ptr));//注意,用的是unique_ptr,传递参数的时候,只能转移,不是copy,因此要用到move函数。。这里再复习一下一个坑点,move函数的作用是 将一个左值变成右值,本质上是调用了 移动构造函数
mythread.join();
}
shared_ptr,注意要用move
class Teacher162 {
public:
void funzhinengptr(shared_ptr ptr) {
cout << "子线程 id为 = " << this_thread::get_id() << " funptr *ptr = " << *ptr << " ptr = " << ptr << endl;
}
};
void main(){
Teacher162 tea;
shared_ptr ptr(new int(20));
cout << "子线程的id = " << this_thread::get_id() << " *ptr = " << *ptr << " ptr = " << ptr << endl;
thread mythread(&Teacher162::funzhinengptr, tea, ptr);//注意,用的是shared_ptr,传递参数的时候,可以copy,
mythread.join();
}
从前面写的例子,都没有 考虑到 线程返回值情况,这个后面再分析一下,目前想不到这个返回值在实际开发中有啥用?