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

目录
  • C++11中thread库join和detach的区别
    • 线程状态
    • 线程环境
    • join和detach的区别
  • 总结

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

总结

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

(0)

相关推荐

  • C++实现CreatThread函数主线程与工作线程交互的方法

    本文实例讲述了C++开启线程CreatThread函数的使用,实现主线程与工作线程交互的功能.分享给大家供大家参考. 具体实现代码如下: 复制代码 代码如下: //线程函数  DWORD WINAPI ThreadProc(LPVOID lpParameter)  {      for (int i=0;i<20;i++)      {          printf("I'm in thread,count=%d\n",i);      }      return 0;  } 

  • 详解C++ thread用法总结

    1,简介 C++11中加入了<thread>头文件,此头文件主要声明了std::thread线程类.C++11的标准类std::thread对线程进行了封装,定义了C++11标准中的一些表示线程的类.用于互斥访问的类与方法等.应用C++11中的std::thread便于多线程程序的移值. std::thread类成员函数: (1).get_id:获取线程ID,返回一个类型为std::thread::id的对象. (2).joinable:检查线程是否可被join.检查thread对象是否标识一

  • C++11 并发指南之std::thread 详解

    上一篇博客<C++11 并发指南一(C++11 多线程初探)>中只是提到了 std::thread 的基本用法,并给出了一个最简单的例子,本文将稍微详细地介绍 std::thread 的用法. std::thread 在 <thread> 头文件中声明,因此使用 std::thread 时需要包含 <thread> 头文件. std::thread 构造 default (1) thread() noexcept; initialization (2) template

  • c++11封装thread库的方法示例

    前言 c++11在语言层面上提供了对thread的支持,由于不同的平台提供了不同线程API,在语言层面提供了对thread的支持可以大大的减小代码移植的工作量. 本文将给大家详细介绍关于c++11封装thread库的相关内容,下面话不多说了,来一起看看详细的介绍吧 基本接口要求 要求std::thread的构造函数 template< class Function, class... Args > explicit thread( Function&& f, Args&

  • C++线程优先级SetThreadPriority的使用实例

    本文实例讲述了C++线程优先级SetThreadPriority的使用方法,分享给大家供大家参考.具体方法如下: 复制代码 代码如下: // ThreadPriority.cpp : 定义控制台应用程序的入口点.  //    #include "stdafx.h"  #include <Windows.h>    DWORD WINAPI ThreadProcIdle(LPVOID lpParameter)  {      for (int i=0;i<20;i++

  • c++11中关于std::thread的join的详解

    std::thread是c++11新引入的线程标准库,通过其可以方便的编写与平台无关的多线程程序,虽然对比针对平台来定制化多线程库会使性能达到最大,但是会丧失了可移植性,这样对比其他的高级语言,可谓是一个不足.终于在c++11承认多线程的标准,可谓可喜可贺!!! 在使用std::thread的时候,对创建的线程有两种操作:等待/分离,也就是join/detach操作.join()操作是在std::thread t(func)后"某个"合适的地方调用,其作用是回收对应创建的线程的资源,避

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

    目录 C++11中thread库join和detach的区别 线程状态 线程环境 join和detach的区别 总结 C++11中thread库join和detach的区别 线程状态 在一个线程的生存期中,可以在多种状态之间转换,不同的操作系统可以实现不同的线程模型,定义许多的线程状态,且每个状态还可以包含多个子状态.但大体来说,所有的操作系统有几种状态是通用的. 就绪态:参与调度,等待被执行,一旦被CPU选中,就立即开始执行. 运行态:占用CPU,正在被运行. 休眠态:暂不参与调度,等待特定的

  • 浅谈Java中的四种引用方式的区别

    强引用.软引用.弱引用.虚引用的概念 强引用(StrongReference) 强引用就是指在程序代码之中普遍存在的,比如下面这段代码中的object和str都是强引用: Object object = new Object(); String str = "hello"; 只要某个对象有强引用与之关联,JVM必定不会回收这个对象,即使在内存不足的情况下,JVM宁愿抛出OutOfMemory错误也不会回收这种对象. 比如下面这段代码: public class Main { publi

  • 浅谈java中BigDecimal的equals与compareTo的区别

    这两天在处理支付金额校验的时候出现了点问题,有个金额比较我用了BigDecimal的equals方法来比较两个金额是否相等,结果导致金额比较出现错误(比如3.0与3.00的比较等). [注:以下所讲都是以sun jdk 1.4.2版本为例,其他版本实现未必一致,请忽略] 首先看一下BigDecimal的equals方法: public boolean equals(Object x){ if (!(x instanceof BigDecimal)) return false; BigDecima

  • 浅谈java中类名.class, class.forName(), getClass()的区别

    Class对象的生成方式如下: 1.类名.class    说明: JVM将使用类装载器, 将类装入内存(前提是:类还没有装入内存),不做类的初始化工作.返回Class的对象 2.Class.forName("类名字符串")  (注:类名字符串是包名+类名) 说明:装入类,并做类的静态初始化,返回Class的对象 3.实例对象.getClass()  说明:对类进行静态初始化.非静态初始化:返回引用o运行时真正所指的对象(因为:子对象的引用可能会赋给父对象的引用变量中)所属的类的Cla

  • 浅谈java中六大时间类的使用和区别

    java.util.Date java.sql.Date java.sql.Time java.sql.Timestamp java.text.SimpleDateFormat java.util.Calendar java.util.Date日期格式为:年月日时分秒 java.sql.Date日期格式为:年月日 java.sql.Time日期格式为:时分秒 java.sql.Timestamp日期格式为:年月日时分秒纳秒(毫微秒) 从数据库中取出来的日期一般都用getTimestamp()方法

  • 浅谈numpy中np.array()与np.asarray的区别以及.tolist

    array和asarray都可以将结构数据转化为ndarray,但是主要区别就是当数据源是ndarray时,array仍然会copy出一个副本,占用新的内存,但asarray不会. 1.输入为列表时 a=[[1,2,3],[4,5,6],[7,8,9]] b=np.array(a) c=np.asarray(a) a[2]=1 print(a) print(b) print(c) 从中我们可以看出np.array与np.asarray功能是一样的,都是将输入转为矩阵格式.当输入是列表的时候,更改

  • 浅谈Java中IO和NIO的本质和区别

    IO的本质 IO的作用就是从外部系统读取数据到java程序中,或者把java程序中输出的数据写回到外部系统.这里的外部系统可能是磁盘,网络流等等. 因为对所有的外部数据的处理都是由操作系统内核来实现的,对于java应用程序来说,只是调用操作系统中相应的接口方法,从而和外部数据进行交互. 所有IO的本质就是对Buffer的处理,我们把数据放入Buffer供系统写入外部数据,或者从系统Buffer中读取从外部系统中读取的数据.如下图所示: 用户空间也就是我们自己的java程序有一个Buffer,系统

  • 浅谈mysql中int(1)和int(10)的区别

    目录 困惑 数据说话 零填充 总结 困惑 最近遇到个问题,有个表的要加个user_id字段,user_id字段可能很大,于是我提mysql工单alter table xxx ADD user_id int(1).领导看到我的sql工单,于是说:这int(1)怕是不够用吧,接下来是一通解释. 其实这不是我第一次遇到这样的问题了,其中不乏有工作5年以上的老司机.包括我经常在也看到同事也一直使用int(10),感觉用了int(1),字段的上限就被限制,真实情况肯定不是这样. 数据说话 我们知道在mys

  • 浅谈PHP中new self()和new static()的区别

    本文介绍了PHP中new self()和new static()的区别,分享给大家,也给自己留个笔记. 1.new static()是在PHP5.3版本中引入的新特性. 2.无论是new static()还是new self(),都是new了一个新的对象. 3.这两个方法new出来的对象有什么区别呢,说白了就是new出来的到底是同一个类实例还是不同的类实例呢? 为了探究上面的问题,我们先上一段简单的代码: class Father { public function getNewFather(

  • 浅谈Java中BIO、NIO和AIO的区别和应用场景

    最近一直在准备面试,为了使自己的Java水平更上一个档次,拜读了李林峰老师的<Netty权威指南>,了解了Java关于IO的发展和最新的技术,真是受益匪浅,现在把我总结的关于BIO.NIO和AIO的区别和应用场景概述一遍. 在此之前,先弄清几个概念: 1.同步:使用同步IO时,Java自己处理IO读写. 2.异步:使用异步IO时,Java将IO读写委托给OS处理,需要将数据缓冲区地址和大小传给OS,完成后OS通知Java处理(回调). 3.阻塞:使用阻塞IO时,Java调用会一直阻塞到读写完成

随机推荐