浅谈C++中thread库join和detach的区别

时间:2021-11-19 06:19:21

C++11中thread库join和detach的区别

线程状态

在一个线程的生存期中,可以在多种状态之间转换,不同的操作系统可以实现不同的线程模型,定义许多的线程状态,且每个状态还可以包含多个子状态。但大体来说,所有的操作系统有几种状态是通用的。

  • 就绪态:参与调度,等待被执行,一旦被CPU选中,就立即开始执行。
  • 运行态:占用CPU,正在被运行。
  • 休眠态:暂不参与调度,等待特定的事件发生后转化为就绪态。
  • 中止态:已经运行完毕,等待回收线程资源。

线程环境

线程存在于进程之中,进程内所有的全局资源对于内部每个线程都是可见的。

进程内典型的全局资源(线程可见资源)如下:

  • 代码区:意味着当前进程空间内所有的函数代码均可见,对于每个线程来说,都是可见的。
  • 静态存储区:全局变量、可访问的静态变量。
  • 动态存储区:动态生成的变量(new)。

线程内典型的局部资源如下

1.本地栈空间:存放本线程的函数调用栈,函数内部的局部变量等。

2.部分寄存器变量:线程下一步要执行代码的指针偏移量。

join和detach的区别

一个进程发起后,会首先生成一个缺省的线程,通常称这个线程为主线程,C/C++程序中,主线程就是通过main函数进入的线程,由主线程衍生的线程成为从线程(也称之为子线程),从线程也可以有自己的入口函数,相当于主线程的main函数,这个函数由用户指定。通常使用thread创建子线程。通过thread构造函数中传入函数指针实现,在指定线程入口函数时,也可以指定入口函数的参数。

最常见的线程模型中,除主线程较为特殊之外,其他线程一旦被创建,相互之间就是对等关系,不存在隐含的层次关系。每个进程可创建的最大线程数由具体实现决定。

无论在windows中还是Posix中,主线程和子线程的默认关系都是:无论子线程执行完毕与否,一旦主线程执行完毕退出,所有子线程执行都会终止。部分线程保持一种终止执行但还未销毁的状态,而进程必须在其所有线程销毁后销毁,这时整个进程处于僵死状态(可能造成程序崩溃)。

在这种情况下,主线程和子线程通常定义以下两种关系:

1、可会合(joinable):这种关系下,主线程需要明确执行等待操作,在子线程结束后,主线程的等待操作执行完毕,子线程和主线程会合,这时主线程继续执行等待操作之后的下一步操作。主线程必须会合可会合的子线程。在主线程的线程函数内部调用子线程对象的wait函数,即使子线程能够在主线程之前执行完毕,进入终止态,也必须执行会合操作,否则,系统永远不会主动销毁线程,分配给该线程的系统资源也永远不会释放。

2、相分离(detached):这种关系下,子线程无需和主线程会合,也就是相分离的,这种情况下,子线程一旦进入终止状态,这种方式常用在线程数较多的情况下。有时让主线程逐个等待子线程结束或者让主线程安排每个子线程结束的等待顺序,是很困难或不可能的,所以在并发子线程较多的情况下,这种方式也会经常使用。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注服务器之家的更多内容!

原文链接:https://blog.csdn.net/qq135595696/article/details/121387692