先总结延申以下前面(一)所讲的内容。
主线程从main()函数开始执行,我们创建的线程也需要一个函数作为入口开始执行,所以第一步先初始化函数。
整个进程是否执行完毕的标志是主线程是否执行完毕,一般情况下,如果想要保持子线程的运行状态,那么要主线程保持运行。
本章从两方面介绍创建线程的方法:
一、用函数创建线程:
关键词:thread(类),join() ,detach(),joinable().
join(),阻塞主线程,等待子线程执行完毕后,才到主线程执行。
detach(),分离主线程,主线程和子线程各走各的,所以会出现多次运行会发现,运行结果可能不同,这时候需要考虑一个问题,主线程如果执行完了,子线程还没跑完,这就可能出现一定问题了。
joinable(),判断是否使用了join()或者detach(),是返回false,否返回true。
注意:join()和detach()不能同时使用,这两个函数本来就有互斥的关系。
1 #include <iostream> 2 #include <thread> 3 void my_thread() 4 { 5 for (int i = 1; i <= 5; i++) 6 { 7 cout << "my_thread" << i << endl; 8 } 9 } 10 int main() 11 { 12 thread my_threadObj(my_thread); //创建一个子线程,并传入子线程的函数入口my_thread 13 if (my_threadObj.joinable()) //返回true代表没有使用join()或者detch() 14 { 15 my_threadObj.join(); //阻塞主线程,并让主线程等待子线程执行完 16 } 17 else 18 { 19 return -1; 20 } 21 //my_threadObj.detach(); //分离主线程,子线程与主线程各自运行,所以每次运行结果可能不同 22 for (int i = 1; i <=5; i++) 23 { 24 cout << "main_thread" << i << endl; 25 } 26 return 0; 27 }
二、其他方法创建线程
1.用类对象
一旦用了detach()将子线程和主线程分离开,那么主线程执行完后,对象ca已经被销毁,但实际上在子线程上的对象并不是ca,而是ca的拷贝对象,它并没有被销毁,还存在与子线程中。
1 class CA 2 { 3 public: 4 void operator()() 5 { 6 cout << "my_thread1" << endl; 7 cout << "my_thread2" << endl; 8 cout << "my_thread3" << endl; 9 cout << "my_thread4" << endl; 10 cout << "my_thread5" << endl; 11 } 12 CA() 13 { 14 cout << "调用构造函数" << endl; 15 } 16 CA(const CA&a) 17 { 18 cout << "调用拷贝构造函数" << endl; 19 } 20 ~CA() 21 { 22 cout << "调用析构函数" << endl; 23 } 24 }; 25 int main() 26 { 27 CA ca; 28 thread my_threadObj(ca); //创建一个子线程,可调用对象为ca 29 if (my_threadObj.joinable()) //返回true代表没有使用join()或者detch() 30 { 31 my_threadObj.join(); //阻塞主线程,并让主线程等待子线程执行完 32 } 33 for (int i = 1; i <= 5; i++) 34 { 35 cout << "main_thread" << i << endl; 36 } 37 return 0; 38 }
2.用lambda表达式
1 int main() 2 { 3 auto mylabda_thread = [] 4 { 5 for (int i = 1; i <= 5; i++) 6 { 7 cout << "mythread" << i << endl; 8 } 9 }; 10 thread mythreadObj(mylabda_thread); 11 mythreadObj.detach(); 12 for (int i = 1; i <= 5; i++) 13 { 14 cout << "main_thread" << i << endl; 15 } 16 return 0; 17 }