烟台制作网站的公司简介/网络营销推广方式包括
注:可能本篇博客中的程序的运行结果在不同情况下会有所差别
概念: 主线程从main()开始执行,那么我们自己创建的线程,也需要从一个函数开始运行(初始函数),一旦这个函数与运行完毕,就代表我们这个线程运行结束。
- 整个进程是否执行完毕的标志是 主线程是否执行完,如果主线程执行完了,那么就代表整个进程执行完了
- 一般情况下,如果其它子线程还没有执行完毕,那么这些子线程也会被操作系统强行终止
- 一般情况下,我们得到一个结论;如果想要保持子线程(自己用代码创建的线程)的运行状态的话,那么大家就要让主线程一直保持运行,不要让主线程运行完毕;
特殊情况:detach()函数
一般程序包含部分:
- 一个头文件thread(是个标准库里的类)
- 初始函数
- main中开始写代码
多线程即意味着,有两个线程在跑,相当于整个程序的执行有两条路在走,所以,可以同时干两件事,即使一条线程被堵住了,另外一条线还是可以通行的。
一,普通情况:
#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); //(1)创建了线程,线程执行起点(入口)show();(2)show线程开始执行cout << "Hello 1" << endl;cout << "Hello 2" << endl;cout << "Hello 3" << endl;cout << "Hello 4" << endl;return 0;
}
运行结果:
可以得出输出结果混乱,并且程序异常。
原因:
因为主线程和自己创建的线程是两条路,所以主线程的运行过程中和自己创建线程可以交叉运行,比如第一行中子线程第一句"cout << "子线程开始执行1" << endl;"中的“endl”还没有输出,主线程就输出了。
所以可能会出现主线程先运行结束,但是子线程还没运行完,此时系统退出,就会产生报错的情况。因此系统会提示异常
如果主线程执行完毕了,但是子线程没有执行完毕,这种程序是不合格的,写出来的程序也是不稳定的
一个书写良好的程序,应该是主线程等待子线程执行完毕,自己才能够最终退出。
二,使用join()函数
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()之后,此时与这个主线程关联的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()函数
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。