最近在学习c++多线程,一直不知道join()函数是如何运行的,它是如何卡住线程的,直到最近看了许多博客才有了一点小小的理解,在这里给大家分享一下,如有错误,还请大家多多批评。
首先,我们先来看一下join函数的作用,这一句非常重要,下面会反复用到,大家一定要牢记<<join()函数在运行的时候会卡住主线程,并让当前已经start(在c++中没有start,线程自创建起就开始执行了)的子线程继续运行,直到调用.join的这个线程运行完毕。>>
我们先来看一个简单的例子:
这里我在main函数中进行代码的编写
1.首先我们先来看第一种情况
#include <iostream>
using namespace std;
#include <thread>
#include <mutex>
mutex mtx;
void fun1()
{
mtx.lock();
for (int i = 1; i < 4; i++)
{
cout << "线程t1:" << i << endl;
}
mtx.unlock();
}
void fun2()
{
mtx.lock();
for (int i = 1; i < 4; i++)
{
cout << "线程t2:" << i << endl;
}
mtx.unlock();
}
int main()
{
thread t1(fun1);
//t1.join();
thread t2(fun2);
//t2.join();
cout << "主线程运行结束" << endl;
system("pause");
return 0;
}
不使用join函数,这是主线程和子线程(t1,t2)同时执行,这里需要注意的是子线程t1和t2同一时间只会有一个在执行,因为我们对fun1和fun2加了锁,这里可能会有些同学比较蒙啊,我在深入一下,就是同一时间只能有一个线程在执行,如果线程t1先进行了加锁,那么t2就会阻塞挂起,此时t1和主线程同时执行,反之,同理,(这里为什么先输出"主线程运行结束",我个人认为应该是主线程执行的比较快的原因。),这里根据t1和t2获取锁的先后顺序可能不同有两种结果,贴一下结果
大家可以多运行几次自行观察哈。
2.第二种情况对t1和t2均含有join函数,这里根据join函数的位置不同也有两种情况
2.1
t1.join()跟在线程t1后面,同时t2.join跟在线程t2后面,此时,只有一种输出情况,即如下图所示
上文我们已经说过了,join函数被调用后会卡住主线程,那么主线程被阻塞,直到调用join函数的这个线程执行完并解锁后主函数才能被重新恢复使用,同时由于对fun1加了锁此时线程t2也被阻塞,故只有线程t1在执行,当线程t1执行完后,释放锁,此时t2线程被激活,同时再次调用join函数卡住主线程,执行同t1,最后主线程被激活,执行主线程,然后执行完毕,程序退出。
2.2
这种情况下t1和t2的join函数在两个线程下面,这种情况下对两个线程的执行过程不影响,原因还是我让大家重点记忆的那句话,再看一下<<join()函数在运行的时候会卡住主线程,并让当前已经start(在c++中没有start,线程自创建起就开始执行了)的子线程继续运行,直到调用.join的这个线程运行完毕。>>请你要时刻记住调用join函数只是卡住主线程,并不影响子线程,除了主线程最后执行,其他都和第一种情况一样。
3.
还有只有一个线程含有join的情况,这里我就不解释了,留给大家自行去探索,算是留给大家的作业题。如果这篇文章对你有帮助的话,请别忘了给小小华子点个赞。