网上所说的join是阻塞主线程,直到分线程执行完毕。仅从文字很难理解,于是随便写了代码做测试,进一步理解join的作用。
#include<iostream>
#include<thread>
using namespace std;
void test(int n){
for(int i=0;i<=20;i++){
cout<<"test1"<<" : "<<i<<endl;
}
}
void test1(int n){
for(int i=0;i<=20;i++){
cout<<"test2"<<" : "<<i<<endl;
}
}
int main()
{
cout<<"begin main"<<endl;
thread t1(test,10);
cout<<"t1创建后"<<endl;
thread t2(test1,15);
cout<<"t2创建后"<<endl;
t1.join();
cout<<"t1 Join后"<<endl;
t2.join();
cout<<"t2 Join后"<<endl;
return 0;
}
输出结果如下:
begin main
test1 : 0
test1 : 1
test1 : 2
test1 : 3
test1 : 4
test1 : 5
test1 : 6
test1 : t1创建后7
test1 : 8
test1 : 9
test1 : 10
test1 : 11
test1 : 12
test1 : 13
test1 : 14
test1 : 15
test1 : 16
test1 : 17
test1 : 18
test1 : 19
test1 : 20
test2 : 0
test2 : 1
t2创建后test2 : 2
test2 : 3
test2 : 4
test2 : 5
test2 : 6
test2 : 7
test2 : 8
test2 : 9
test2 : 10
test2 : 11
test2 : 12
test2 : 13
test2 : 14
test2 : 15
test2 : 16
test2 : 17
test2 : 18
test2 : 19
test2 : 20
t1 Join后
t2 Join后
可以发现是杂乱无章的,且每次结果不同。
更改后主函数join和线程创建的顺序后,代码和结果如下:
int main()
{
cout<<"begin main"<<endl;
thread t1(test,10);
cout<<"t1创建后"<<endl;
t1.join();
cout<<"t1 Join后"<<endl;
thread t2(test1,15);
cout<<"t2创建后"<<endl;
t2.join();
cout<<"t2 Join后"<<endl;
return 0;
}
结果:
begin main
test1 : 0t1创建后
test1 : 1
test1 : 2
test1 : 3
test1 : 4
test1 : 5
test1 : 6
test1 : 7
test1 : 8
test1 : 9
test1 : 10
test1 : 11
test1 : 12
test1 : 13
test1 : 14
test1 : 15
test1 : 16
test1 : 17
test1 : 18
test1 : 19
test1 : 20
t1 Join后
test2 : 0t2创建后
test2 : 1
test2 : 2
test2 : 3
test2 : 4
test2 : 5
test2 : 6
test2 : 7
test2 : 8
test2 : 9
test2 : 10
test2 : 11
test2 : 12
test2 : 13
test2 : 14
test2 :
15
test2 : 16
test2 : 17
test2 : 18
test2 : 19
test2 : 20
t2 Join后
与第一次不同的是,本次的两次调用test1执行完后才进行test2的执行,原因是由于t1.join阻拦了主线程的工作,这样的结果也就能理解join的作用了。
网上有些是java的的多线程编程,java有一个线程开始运行的函数,但是C++没有,应该是在创建的时候就已经运行线程了。以第二次实验的线程2为例,执行子test2后(子线程的join前),主线程也在正常执行(输出“t2创建后”),此时是主线程和子线程是同时执行的,所以出现了混乱输出。
所以如果你碰到了多个线程代码,比如这样:
thread t1.....
thread t2.....
thread t3.....
t1.join()
t2.join()
t3.join()
其实这三个线程的关系是并行的,虽然在主线程创建中稍有先后顺序,但实际应该是三个子线程是并行关系,然后主线程阻塞。