Thread
C++11多线程编程
进程与线程
- 进程就是正在运行的程序
- 线程就是进程中的进程
- 多线程可以提高效率。
- 线程的多少取决于CPU的核数
如下图,如果是串行的话就必须顺序执行,但如果并行的话你就可以在同一时间内干多个事情。但同时要注意你的“核数”,你不能同时刷抖音和听音乐,因为你没有四个耳朵,亦或者说你的手机同一时间内只能处理一个应用播放声音。
C++11 Thread
- 准备工具 Visual Studio
- 线程库 thread
1 |
使用thread创建一个线程
1 | void PrintHelloWorld() |
运行调试后,会得到下面结果:
我们发现报错了,为什么会这样呢?
可以理解为main里是主线程,一开始我们便创建了一个子线程,并让其执行PrintHelloWorld的函数。当子线程没有执行完毕的时候,主线程已执行完毕。主线程不会等待子线程执行完毕,可能子线程才执行到Hello,主程序已经return 0了,所以出现报错;所以说主线程和子线程是并发运行的!
1 | std::cout<<"HelloworldMain"<<std::endl; |
当我们再次加入一行代码时发现,先输出的是主线程的HelloworldMain,接下来才是子线程的Helloworld。从这里我们可以看出:创建线程是需要时间的。
如何解决主线程和子线程先后结束时间不同而引起的程序崩溃?
函数thread.join()
在 C++ 中,std::thread::join() 的作用是 等待子线程执行完毕,然后主线程才继续执行。如果没有 join(),主线程可能会在子线程执行完成之前就结束,导致未定义行为程序报错。
1 | std::thread thread1(PrintHelloWorld); |
当我们添加了thread1.join()之后,相当于告诉主线程:“大哥你先等我弄完你再往下走,别丢下我!” (演示注释掉thread1.join()的情况)
join的作用是:确保子线程完成,执行顺序可控,但是会阻塞主线程,直到子线程完成。
阻塞示例 (joinable()用于判断线程是否可以使用join函数,返回的是一个bool值)
1 |
|
函数thread.detach()
让子线程“脱离”主线程,主线程不再管理它。
1 | std::thread thread1(PrintHelloWorld); |
你可以干你的事情,我也可以干我的事情,不管你了。像请客吃饭,请客的人把单买了之后说我先走一步,你们随意。对比上面的阻塞,我们发现detach是并发的。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Explainfuture's Blog!