本文用最简单易懂的实际案例,讲清楚了 join 的实际内涵,保证你过目不忘。
join 函数是我们接触C++多线程 thread 遇到的第一个函数。
比如:
- int main()
- {
- thread t(f);
- t.join();
- }
join 表示线程 t 运行起来了。但是,t 也阻碍了 main 线程的退出(谁调用,阻塞谁)。
也就是说,如果 f 的执行需要 5秒钟, main也要等待5秒才能退出。
这看起来非常合理,因为 main 就应该等待 t 退出之后再退出。
多个线程都以 join 的方式启动的时候,main 就要等到最后。
比如:
- #include
- #include
- #include
- #include
- #include
- using namespace std;
- using namespace chrono;
-
- auto start = system_clock::now();
-
- void print_elapsed(string msg)
- {
- cout << msg << " at[" << duration_cast
(system_clock::now()-start).count()<<"]" << endl; - }
- void task_fun(int i)
- {
- print_elapsed("task_fun " + to_string( i) + " start!");
- // simulate expensive operation
- this_thread::sleep_for(seconds(i));
- print_elapsed("task_fun " + to_string(i) + " finished!");
- }
-
- int main()
- {
- print_elapsed( "main begin...");
- thread task1(task_fun, 9);//线程这时候就已经开始启动
- thread task2(task_fun, 6);//线程这时候就已经开始启动
- thread task3(task_fun, 3);//线程这时候就已经开始启动
- thread task4(task_fun, 12);//线程这时候就已经开始启动
-
- print_elapsed("waiting for all tasks to finish...");
- task1.join();//main第一次阻塞,给前面的线程机会执行到各自打印的语句
- print_elapsed("task1.join() finished");//第9秒钟之后,main终于等到了task1的退出,在这之前task3(第3秒执行完毕),task2(第6秒),执行完毕
- task2.join();//这里不会有阻塞,因为在第6秒的时候task2就已经退出了
- print_elapsed("task2.join() finished");
- task3.join();//这里不会有阻塞,因为在第3秒的时候task2就已经退出了
- print_elapsed("task3.join() finished");
- task4.join();//这里会再次阻塞3秒(从第9秒阻塞到第12秒)
- print_elapsed("task4.join() finished");
- print_elapsed("all tasks to finished.");
- }