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 ...
随机推荐
- ArcGIS DataStore手册——管理篇
第二章:ArcGIS DataStore管理维护 1.备份管理 备份的目的在于发生原始数据损坏或其他突发情况时,可避免数据丢失,并可快速的使用备份数据来恢复,以保证服务仍可使用. 单机模式下,可使用D ...
- _itoa atoi、atof、itoa、itow _itoa_s 类型转换使用说明
原文:http://www.cnblogs.com/lidabo/archive/2012/07/10/2584706.html _itoa 功能:把一整数转换为字符串 用法:char * _itoa ...
- java jdk切换出现的问题 jdk切换失败(转)
1.问题:同时装两个版本的jdk时出现的问题(本次是1.7和1.8的版本),因为eclipse要求1.8版本的,但是我的Windows默认版本是1.7,导致无法启动eclipse 2.因为做开发的时候 ...
- SQL Server ->>监控和管理Tempdb
Tempdb作为一个公共数据库,存储着一些临时的数据.有些是用户自己创建的,有些是SQL Server自己创建的.Tempdb空间被使用的一些常见场景有 用户自定义:临时表和表变量.游标. SQL S ...
- leetcode-Restore IP Addresses-ZZ
http://www.cnblogs.com/remlostime/archive/2012/11/14/2770072.html class Solution { private: vector&l ...
- TcpListener、TcpClient
1.TcpClient using System; using System.Text; using System.Net.Sockets; namespace tcpclient { class t ...
- Linux内核收包过程
net/core/dev.c int __init net_dev_init(void) { queue->backlog.poll = process_backlog; open_softir ...
- 关于函数指针与c++多态
原文 https://www.cnblogs.com/zhchngzng/p/4013031.html 虚函数是实现多态的重要元素,请看: class A { public: void a0(){c ...
- AngularJs学习笔记--Understanding the Model Component
原版地址:http://docs.angularjs.org/guide/dev_guide.mvc.understanding_model 在angular文档讨论的上下文中,术语“model”可以 ...
- Codeforces Round #436 (Div. 2)【A、B、C、D、E】
Codeforces Round #436 (Div. 2) 敲出一身冷汗...感觉自己宛如智障:( codeforces 864 A. Fair Game[水] 题意:已知n为偶数,有n张卡片,每张 ...