注:可能本篇博客中的程序的运行结果在不同情况下会有所差别
概念: 主线程从main()开始执行,那么我们自己创建的线程,也需要从一个函数开始运行(初始函数),一旦这个函数与运行完毕,就代表我们这个线程运行结束。
整个进程是否执行完毕的标志是 主线程是否执行完,如果主线程执行完了,那么就代表整个进程执行完了一般情况下,如果其它子线程还没有执行完毕,那么这些子线程也会被操作系统强行终止一般情况下,我们得到一个结论;如果想要保持子线程(自己用代码创建的线程)的运行状态的话,那么大家就要让主线程一直保持运行,不要让主线程运行完毕; 特殊情况:detach()函数一般程序包含部分:
一个头文件thread(是个标准库里的类)初始函数 main中开始写代码 多线程即意味着,有两个线程在跑,相当于整个程序的执行有两条路在走,所以,可以同时干两件事,即使一条线程被堵住了,另外一条线还是可以通行的。运行结果:
可以得出输出结果混乱,并且程序异常。
原因:
因为主线程和自己创建的线程是两条路,所以主线程的运行过程中和自己创建线程可以交叉运行,比如第一行中子线程第一句"cout << "子线程开始执行1" << endl;"中的“endl”还没有输出,主线程就输出了。 所以可能会出现主线程先运行结束,但是子线程还没运行完,此时系统退出,就会产生报错的情况。因此系统会提示异常
如果主线程执行完毕了,但是子线程没有执行完毕,这种程序是不合格的,写出来的程序也是不稳定的 一个书写良好的程序,应该是主线程等待子线程执行完毕,自己才能够最终退出。
join():加入/汇合,就是阻塞,阻塞主线程,让主线程等待子线程执行完毕,然后子线程与主线程汇合。然后主线程再往下走
阻塞主线程并等待show子线程执行完 test1.join(); //主线程到这里产生阻塞,等待show()执行,当子线程执行完毕,这个join()就执行完毕,主线程再继续往下走
#include<iostream> #include<thread> using namespace std; void show() { cout << "子线程开始执行1" << endl; cout << "子线程开始执行2" << endl; cout << "子线程开始执行3" << endl; cout << "子线程开始执行4" << endl; //.... //.... cout << "子线程执行结束" << endl; } int main() { thread test1(show); test1.join(); cout << "Hello 1" << endl; cout << "Hello 2" << endl; cout << "Hello 3" << endl; cout << "Hello 4" << endl; system("pause"); return 0; }从执行结果可以看出,自己创建的线程函数show()开始执行,然后再主线程开始执行。
detach():传统多线程程序主线程要等待子线程执行完毕,然后自己再最后退出;detach的效果就是分离,也就是主线程不和子线程汇合了,你主线程执行你的,我子线程执行我的,你主线程也不必等我子线程运行结果,你可以先执行结束,这并不影响我子线程的执行引入detach()的原因:我们创建了很多子线程,让主线程逐个等待子线程结束,这种编程方法不好,所以引入了detach
一旦detach()之后,此时与这个主线程关联的detach对象就会失去与这个主线程的关联,此时这个子线程就会驻留在后台 运行。(主线程跟该子线程失去联系) 这个子线程就相当于被C++运行时库接管,当这个子线程执行完毕,由运行时库负责清理该线程的相关资源(守护线程)detach使线程show失去我们自己的控制一旦使用了detach(),就不能再使用join(),否则系统会报告异常 #include<iostream> #include<thread> using namespace std; void show() { cout << "子线程开始执行1" << endl; cout << "子线程开始执行2" << endl; cout << "子线程开始执行3" << endl; cout << "子线程开始执行4" << endl; cout << "子线程开始执行5" << endl; cout << "子线程开始执行6" << endl; cout << "子线程开始执行7" << endl; cout << "子线程开始执行8" << endl; //.... //.... cout << "子线程执行结束" << endl; } int main() { thread test1(show); test1.detach(); cout << "Hello 1" << endl; cout << "Hello 2" << endl; system("pause"); return 0; }此时因为使用的是detach()函数,所以就算此时主进程运行结束时子进程还没有结束,程序仍然不会报错,因为子进程可以在运行时库中运行。但是如果没有这个函数,若主程序结束时子进程还没结束,就会产生报错。
因为此时两个线程互不干扰,所以多次运行的结果会有差别,取决于两个线程以哪一种方式进行调用
joinable():判断是否可以成功使用join()或者detach()的;返回true(可以join或者detach)或者false(不能)
#include<iostream> #include<thread> using namespace std; void show() { cout << "子线程开始执行1" << endl; //.... //.... cout << "子线程执行结束" << endl; } int main() { thread test1(show); if (test1.joinable() == true) { test1.join(); } else{ cout << "不能进行join或者detach" << endl; } if (test1.joinable() == true){ test1.join(); } else{ cout << "不能进行join或者detach" << endl; } cout << "Hello 1" << endl; cout << "Hello 2" << endl; system("pause"); return 0; }本段程序中通过两个if判断,当第一个判断时,此时test1还没有join所以判断结果为TRUE,第二次判断时,因为第一次判断后,会产生join,所以第二次判断时,结果为false。