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. Django—middleware

    一.Django中间件的请求周期 我们从浏览器发出一个请求 Request,得到一个响应后的内容 HttpResponse ,这个请求传递到 Django的过程如下: 也就是说,每一个请求都是先通过中 ...

  2. 02_zookeeper配置

    [zoo.cfg] * tickTime:用于计算的时间单元.比如session超时:N*tickTime * initLimit:用于集群,允许从节点连接并且同步到master节点的初始化连接时间, ...

  3. delphi 获取可执行文件的当前路径

    在Delphi SysUtils 单元中有 ExtractFileDir 与 ExtractFilePath两个类似的函数, 两个函数有以下的区别: ExtractFilePath 传回值的最後一个字 ...

  4. 第三篇:jvm之垃圾回收器

    一.Serial收集器 新生代收集器,在垃圾回收时,必须暂停其他所有的工作线程.即Stop-The-World. 评价:老而无用,食之无味,弃之可惜. 二.ParNew收集器 新生代收集器,seria ...

  5. javascript tips and snippets

    如何给javascript对象动态创建动态key // ES2015 var key = 'DYNAMIC_KEY', obj = { [key]: 'ES6!' }; console.log(obj ...

  6. MVC Dropdownlist数据绑定 默认值

    @Html.DropDownList("Data", (SelectList)ViewBag.Data, new { @class = "form-control cho ...

  7. CASE表达式

    一.简介 官方定义CASE是一种表达式,它基于某种格式,按照格式去编写表达式,其中表达式的逻辑是:指定特定的值与条件列表去匹配,返回对应的值. CASE表达式类似我们编程语言中的 if else 和 ...

  8. 如何申请免费域名证书,以及在IIS上绑定

    1.前往https://freessl.cn/ 申请域名 证书 2.输入邮箱后,点击创建.文件验证方式 会自动下载一个压缩包,把该压缩包放到所申请的域名首层下.(不要重复创建,需要3,5分钟.最好手动 ...

  9. July 20th 2017 Week 29th Thursday

    The darkness is no darkness with you. 有了你,黑暗将不再是黑暗. The darkness will not be driven out if we failed ...

  10. 1100 final standings

    http://acm.timus.ru/problem.aspx?space=1&num=1100 link to the problem make a fast stable sorting ...