detach()之大坑:detach会引起局部变量失效引起线程对内存的非法访问题。
一:传递临时对象作为线程参数
(1.1)要避免的陷阱(解释一)
(1.2)要避免的陷阱(解释一)
事实一:只要用临时构造的A类对象作为参数传递给线程,那么就一定能够在主线程(main函数)执行完毕之前把线程函数的第二个参数构建出来,从而确保即便detach了,子线程也能够安全运行。
总结1:若传递int这种简单类型参数,加你都是值传递,不要用引用,防止节外生枝。
总结2:如果传递类对象,要避免隐式类型转换。应该全部在创建线程这一行的时候构建临时对象出来,然后再线程函数参数里用引用来接,否则系统还会构造一个对象,总共会构造三个对象,所以thread里面的运行第很暴力的。
结论3:建议不使用detach,只是用join,那么就不存在局部变量失效引起其他线程对内存非法访问的问题。
应该像下面这样写:
class A
{
public:
int m_i;
//转换类型构造哈函数,可以把一个int转换成一个A类对象
A(int i) :m_i(i) { cout<<"执行构造函数"<<endl; }
A(const A &may) :m_i(may.m_i) { cout<<"执行拷贝构造函数"<<endl; }
~A() { cout<<"执行析构函数"<<endl; }
};
void myprint(const int i, const A &my)//一定要用引用来接,如果不用引用来接,会生成三个临时对象,造成系统资源的浪费
{
cout << my.m_i << endl;
cout << i << endl;
return;
}
int mian()
{
int x = 2;//若传递int这种简单类型参数,加你都是值传递,不要用引用,防止节外生枝。
int y = 9;
thread mythread(myprint, x, A(y));// A(y)这里生成一个局部对象(可以防止局部变量失效引起其他线程对内存非法访问的问题)
mythread.join(); //但是这里会调用拷贝构造函数,所以会生成两个临时对象。
//mythread.detach();
cout << "主线程即将执行结束" << endl;
return 0;
}
注意:一个简单的类型变量作为引用参数创建一个线程的时候,其实不是对这个局部变量的引用,这里其实是拷贝,即生成了一个副本,
所以用detach主线程结束系统回收局部变量后不会引起局部变量在其他线程中非法引用的问题。

二:传递临时对象作为线程参数(继续)(测试大法:发现一些比较神奇的蛛丝马迹)
2.1线程id概念:id是一个数字,每个线程(不管是主线程还是子线程)实际上都对应一个数字,而且每个线程对应的这个数字是不相同的,也就是说不同的线程,它的线程id(数字)必然是不相同的。线程id可以用c++标准库里的函数来获取,
即就是:std::this_thread::get_id()来获取。
2.2临时对象构造时机捕获:
class A
{
public:
int m_i;
//转换类型构造哈函数,可以把一个int转换成一个A类对象
A(int i) :m_i(i) { cout<<"执行构造函数"<<this<<"threadid:"<<std::this_thread::get_id()<<endl; }
A(const A &may) :m_i(may.m_i) { cout<<"执行拷贝构造函数"<<this<<"threadid:"<<std::this_thread::get_id()<<endl;}
~A() { cout<<"执行析构函数"<<this<<"threadid:"<<std::this_thread::get_id()<<endl; }
};
void myprint2(const A &my)//一定要用引用来接,如果不用引用来接,会生成三个临时对象,造成系统资源的浪费
{
cout<<"子线程的参数地址是:"<<&my<<"threadid:"<<std::this_thread::get_id()<<endl;
}
int mian()
{
cout<<"主线程的id:"<<std::this_thread::get_id()<<endl;
int y = 2;//若传递int这种简单类型参数,加你都是值传递,不要用引用,防止节外生枝。
thread mythread(myprint, A(y));// A(y)这里生成一个局部对象,在主线程中生成这个临时对象,所以不用担心detach的问题(可以防止局部变量失效引起其他线程对内存非法访问的问题),但是这里会调用拷贝构造函数,所以会生成两个临时对象。
//thread mythread(myprint, y) //这里生成的临时对象是在子线程中生成的,所有可能会引起主线程结束之后子线程对内存的非法访问问题。
mythread.join();
//mythread.detach();
cout << "主线程即将执行结束" << endl;
return 0;
}

detach()之大坑:detach会引起局部变量失效引起线程对内存的非法访问题。的更多相关文章

  1. detach() 使用和.detach()和.data的区别 、cpu()函数的作用

    detach() 使用和.detach()和.data的区别 .cpu()函数的作用 待办 detach使用 https://blog.csdn.net/qq_27825451/article/det ...

  2. muParser公式库使用简介( 转)

    muParser是一个跨平台的公式解析库,它可以自定义多参数函数,自定义常量.变量及一元前缀.后缀操作符,二元操作符等,它将公式编译成字节码,所以计算起来非常快. 当前版本V1.28,官方网址http ...

  3. Jquery empty() remove() detach() 方法的区别

    方法简介: empty() This method removes not only child (and other descendant) elements, but also any text ...

  4. 转载JQuery 中empty, remove 和 detach的区别

    转载 http://www.cnblogs.com/lisongy/p/4109420.html .empty()  描述: 从DOM中移除集合中匹配元素的所有子节点. 这个方法不接受任何参数. 这个 ...

  5. VC中的Attach和Detach

    CWnd,CDC, Cxxx等都是MFC的类,这些类提供了很多成员函数来执行系统调用等操作,但是核心的类成员数据都是 句柄,(包括窗口句柄,DC句柄,线程句柄等).  m_hWnd  m_hDC  m ...

  6. jQuery中删除方法empty(),remove()和detach()的区别

    empty():清空匹配的元素集合中所有的子节点,自身节点和事件都未被删除. remove():这个方法不会把匹配的元素从jQuery对象中删除,因而可以在将来再使用这些匹配的元素.但除了这个元素本身 ...

  7. 探索jquery方法中empty,remove与detach的区别

    最近一直疑惑此三种方法的具体区别在于何处,随即想弄明白其具体的区别,看了一些说明,也依照官方文档,终于把这三个方法弄明白了,果然功夫不负有心人,继续努力. 上正文,先简单介绍下这三种方法 .empty ...

  8. 揭秘 Kubernetes attach/detach controller 逻辑漏洞致使 pod 启动失败

    前言 本文主要通过深入学习k8s attach/detach controller源码,了解现网案例发现的attach/detach controller bug发生的原委,并给出解决方案. 看完本文 ...

  9. pytorch训练GAN时的detach()

    我最近在学使用Pytorch写GAN代码,发现有些代码在训练部分细节有略微不同,其中有的人用到了detach()函数截断梯度流,有的人没用detch(),取而代之的是在损失函数在反向传播过程中将bac ...

随机推荐

  1. jQuery和css3控制箭头丝滑旋转

    问题: 我们经常会遇见点击一个小三角使之丝滑的旋转180度上下旋转,怎么实现呢,需要css3搭配jq 来处理 如图:1.点击前 2.点击后(效果丝滑旋转)                 1.html ...

  2. 安装Chrome driver/ IE driver

    2014-08-15 11:38 22100人阅读 评论(0) 收藏 举报  分类: python基础学习(97)  >>>安装Chrome driver chrome driver ...

  3. 【NLP_Stanford课堂】拼写校正

    在多种应用比如word中都有拼写检查和校正功能,具体步骤分为: 拼写错误检测 拼写错误校正: 自动校正:hte -> the 建议一个校正 建议多个校正 拼写错误类型: Non-word Err ...

  4. Eclipse控制台输出信息的控制(引用其他人的博客)

    当你在Eclipse中 running/debugging一个应用程序的时候,有关该应用程序的运行调试信息及日志信息都会输出到控制台(console )显示,但是Eclipse只会显示最后一部分的日志 ...

  5. .net通过代码发送邮件

    关键代码: 需要引用命名空间: using System.Net.Mail;using System.Net; MailMessage mailObj = new MailMessage(); mai ...

  6. pc端配置详细 2017级机械设计新生 史浩然

    品牌名称:SAMSUNG/三星         证书状态:有效        申请人名称:苏州三星电子电脑有限公司     型号:940X3K-K01       操作系统:window8.1 产品名 ...

  7. July 18th 2017 Week 29th Tuesday

    My heart is stronger now that you are in it. 我的心里有了你,从此变得更强大. You will no longer feel lonely if ther ...

  8. R在Centos下安装

    R语言是主要用于统计分析.绘图的语言和操作环境. 官方网站: http://www.r-project.org/ Windows下面有直接的安装包,直接下载安装很方便,但是对于刚出的CentOS6.0 ...

  9. ASP.NET Web API编程——构建api帮助文档

    1 概要 创建ASP.NET Web Api 时模板自带Help Pages框架. 2 问题 1)使用VS创建Web Api项目时,模板将Help Pages框架自动集成到其中,使得Web Api项目 ...

  10. 开源项目之kisso

    kisso开源项目:https://gitee.com/baomidou/kisso 一.简介 kisso  =  cookie sso 基于 Cookie 的 SSO 中间件,它是一把快速开发 ja ...