detach()之大坑:detach会引起局部变量失效引起线程对内存的非法访问题。
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会引起局部变量失效引起线程对内存的非法访问题。的更多相关文章
- detach() 使用和.detach()和.data的区别 、cpu()函数的作用
detach() 使用和.detach()和.data的区别 .cpu()函数的作用 待办 detach使用 https://blog.csdn.net/qq_27825451/article/det ...
- muParser公式库使用简介( 转)
muParser是一个跨平台的公式解析库,它可以自定义多参数函数,自定义常量.变量及一元前缀.后缀操作符,二元操作符等,它将公式编译成字节码,所以计算起来非常快. 当前版本V1.28,官方网址http ...
- Jquery empty() remove() detach() 方法的区别
方法简介: empty() This method removes not only child (and other descendant) elements, but also any text ...
- 转载JQuery 中empty, remove 和 detach的区别
转载 http://www.cnblogs.com/lisongy/p/4109420.html .empty() 描述: 从DOM中移除集合中匹配元素的所有子节点. 这个方法不接受任何参数. 这个 ...
- VC中的Attach和Detach
CWnd,CDC, Cxxx等都是MFC的类,这些类提供了很多成员函数来执行系统调用等操作,但是核心的类成员数据都是 句柄,(包括窗口句柄,DC句柄,线程句柄等). m_hWnd m_hDC m ...
- jQuery中删除方法empty(),remove()和detach()的区别
empty():清空匹配的元素集合中所有的子节点,自身节点和事件都未被删除. remove():这个方法不会把匹配的元素从jQuery对象中删除,因而可以在将来再使用这些匹配的元素.但除了这个元素本身 ...
- 探索jquery方法中empty,remove与detach的区别
最近一直疑惑此三种方法的具体区别在于何处,随即想弄明白其具体的区别,看了一些说明,也依照官方文档,终于把这三个方法弄明白了,果然功夫不负有心人,继续努力. 上正文,先简单介绍下这三种方法 .empty ...
- 揭秘 Kubernetes attach/detach controller 逻辑漏洞致使 pod 启动失败
前言 本文主要通过深入学习k8s attach/detach controller源码,了解现网案例发现的attach/detach controller bug发生的原委,并给出解决方案. 看完本文 ...
- pytorch训练GAN时的detach()
我最近在学使用Pytorch写GAN代码,发现有些代码在训练部分细节有略微不同,其中有的人用到了detach()函数截断梯度流,有的人没用detch(),取而代之的是在损失函数在反向传播过程中将bac ...
随机推荐
- 软件项目技术点(5)——在canvas上绘制动态网格线
AxeSlide软件项目梳理 canvas绘图系列知识点整理 grid类的实现 当鼠标在画布上缩放时,网格能跟着我的鼠标滚动而相应的有放大缩小的效果. 下面是具体实现的代码,draw函数里计算出大 ...
- linux 下解决git clone报错
解决报错:error: The requested URL returned error: 401 Unauthorized while accessing 问题报错:error: The req ...
- siriWave.js的demo
demo.html <style>body { background: #000; }</style> <script src="../siriwave.js& ...
- 2013年未之wpf项目乱述
不知识为何现已很少在网上发帖,貌似人生的方向已经看的七七八八.要么用心工作,要么自主创业.无论怎么样,对于现在的我来说都是一种淡定的选择.作为一个c#程序员,今年下半年开始使用wpf,更觉得wpf将来 ...
- UFW Essentials: Common Firewall Rules and Commands
Introduction UFW is a firewall configuration tool for iptables that is included with Ubuntu by defau ...
- CSS浮动并清除浮动(造成的影响)
一.浮动 CSS浮动 CSS float浮动的深入研究.详解及拓展(一) CSS浮动属性Float详解 块级元素独占一行 块级元素,在页面中独占一行,自上而下排列,也就是传说中的流. 可以 ...
- 利用canvas进行一个饼形图的绘制
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- How to prepare system design questions in a tech interview?
http://blog.baozitraining.org/2014/09/how-to-prepare-system-design-questions.html 如何准备面试中的系统设计问题一直都是 ...
- MongoDB学习笔记——概述
概述 MongoDB是一个跨平台,面向文档的数据库.MongoDB创建的数据库可以实现高可用性,高性能,并且能够轻松拓展. MongodbDB的运行方式主要给予两个概念:集合(collection)和 ...
- python全栈学习笔记(二)网络基础之子网划分
阅读目录 一.ip地址基本知识 1.1 ip地址的结构和分类 1.2 特殊ip地址 1.3 子网掩码 1.4 ip地址申请 二.子网划分 2.1 子网划分概念 2.2 c类子网划分初探 2.3 子网划 ...