2.C++多线程--危险点分析

news/2024/11/7 20:37:38/

1.detach使用时分析


使用detach时,子线程一定不要传入指针


#include<iostream>
#include<thread>
using namespace std;void my_print(const int& num1,const char* str) {cout << num1 << " " << str << endl;
}
//主进程结束后,才开始对子进程中的值进行拷贝。但是主进程释放了str1,子进程接收时会出现问题。
int main() {int num1 = 1;char str1[] = "hello,world!";thread obj1(my_print,num1,str1);obj1.detach();cout << "主进程结束运行" << endl;return 0;
}

如果采用临时类对象作为参数,传入到thread中,thread会调用拷贝构造函数,对传入变量进行拷贝,然后再为自线程所使用。

下面的代码采用引用来接收类对象,如果不采用引用的话,系统还会再构造一次对象,这样会出现3次构造,浪费时间。


#include<iostream>
#include<thread>
using namespace std;class son_thread {
public:int m_a;son_thread(int a):m_a(a) {cout << "构造函数的调用" << endl;}~son_thread() {cout << "析构函数的调用" << endl;}
};void my_print(const int a,const son_thread& st) {cout << a << " " << st.m_a << endl;
}
int main() {int num1 = 1;int num2 = 10;thread obj1(my_print, num1,son_thread(num2));obj1.detach();cout << "主进程结束运行" << endl;return 0;
}

2. 临时对象


1.如果对象采用隐式转换,将会在子线程中进行构造对象;

2.如果对象采用显示转换,将会在主线程中进行构造对象,并会调用拷贝构造函数。

this_thread::get_id()---->显示线程的id号

注意:

当采用隐式传递时,是在子线程进行类对象构造,但是此时主线程已经销毁,主线程内的局部变量已经释放,此时操作会有危险。

当采用显式构造是,首先会在主线程构造出一个临时对象,然后在主线程中进行复制拷贝构造,随后在主线程内将临时对象进行释放。


#include<iostream>
#include<thread>
using namespace std;
class son_thread {
public:int m_a;son_thread(int a) :m_a(a) {cout << "son_thread构造函数调用" << this_thread::get_id() << endl;}son_thread(const son_thread& base):m_a(base.m_a) {cout << "son_thread拷贝构造函数的调用" << this_thread::get_id()<< endl;}~son_thread() {cout << "son_thread析构函数调用" << this_thread::get_id()<< endl;}
};
void my_print(const son_thread& base) {cout << base.m_a << " my_print调用" << this_thread::get_id()<< endl;
}
int main() {int temp_a = 1;cout << "主线程的id:" << this_thread::get_id() << endl;//thread obj1(my_print, temp_a);thread obj1(my_print, son_thread(temp_a));obj1.join();cout << "主线程调用完毕:" << this_thread::get_id() << endl;return 0;
}

 3.传递智能指针、类对象


因为在传递类对象是,子线程会调用拷贝构造函数,因此子线程修改类对象成员变量时,并不会修改主线程内的对象成员变量。

此时我们可以用:std::ref()函数

在传入unique_ptr智能指针时,可以使用std::move()对智能指针进行更改。


#include<iostream>
#include<thread>
using namespace std;
class son_thread {
public:int m_a;son_thread(int a) :m_a(a) {cout << "son_thread构造函数调用" << this_thread::get_id() << endl;}son_thread(const son_thread& base) :m_a(base.m_a) {cout << "son_thread拷贝构造函数的调用" << this_thread::get_id() << endl;}~son_thread() {cout << "son_thread析构函数调用" << this_thread::get_id() << endl;}
};
void my_print(unique_ptr<int>temp_pt) {cout << *temp_pt << " my_print调用" << this_thread::get_id() << endl;
}
int main() {int temp_a = 1;cout << "主线程的id:" << this_thread::get_id() << endl;unique_ptr<int>u_pt(new int (100));thread obj1(my_print, std::move(u_pt));obj1.join();cout << "主线程调用完毕:" << this_thread::get_id() << endl;return 0;
}

4.将类函数的函数作为入口函数 


  


#include<iostream>
#include<thread>using namespace std;
class son_thread {
public:int m_a;son_thread(int a) :m_a(a) {cout << "son_thread构造函数调用" << this_thread::get_id() << endl;}son_thread(const son_thread& base) :m_a(base.m_a) {cout << "son_thread拷贝构造函数的调用" << this_thread::get_id() << endl;}~son_thread() {cout << "son_thread析构函数调用" << this_thread::get_id() << endl;}void my_print(const int a ) {cout << a << " 类内函数的调用" << endl;}
};int main() {cout << "主线程的id:" << this_thread::get_id() << endl;son_thread s1(10);thread obj1(&son_thread::my_print, s1, 100);obj1.join();cout << "主线程调用完毕:" << this_thread::get_id() << endl;return 0;
}


http://www.ppmy.cn/news/211165.html

相关文章

HJ29 字符串加解密

描述 对输入的字符串进行加解密&#xff0c;并输出。 加密方法为&#xff1a; 当内容是英文字母时则用该英文字母的后一个字母替换&#xff0c;同时字母变换大小写,如字母a时则替换为B&#xff1b;字母Z时则替换为a&#xff1b; 当内容是数字时则把该数字加1&#xff0c…

Node.js: express + MySQL + Vue实现图片上传

前段时间用Node.js: express MySQL Vue element组件做了一个小项目&#xff0c;记录一下图片上传的实现。 将图片存入数据库有两种方法&#xff1a; 1&#xff0c;将图片以二进制流的方式存入数据库&#xff08;数据库搬家容易&#xff0c;比较安全&#xff0c;但数据库空间…

android wear 配对找不到手表,如何将多个Android Wear手表与单个手机配对 | MOS86

当谈到普通手表时&#xff0c;许多人会为不同的活动使用不同的手表。 它可以为体育馆提供运动型手表&#xff0c;为办公室提供更好的手表&#xff0c;并为其他一切提供休闲手表。 如果您想通过Android Wear来度过这一生&#xff0c;那么轻松将多块手表连接到主手机上就很容易了…

安卓手表wear开发获取心率

本人在项目开发过程中遇到需要开发一款手表应用&#xff0c;并且需要获取心率等生命体征信息。此处以获取心率举例记录 首先获取权限 <uses-permission android:name"android.permission.BODY_SENSORS" /> 其实只是实现读取心率是比较容易的&#xff0c;接…

从安装包中提取wear OS手表端应用

连接wearOS的安卓手机&#xff0c;一般会把安装包推送到手表&#xff0c;但有时候手表并不会接受推送&#xff08;如小米手表&#xff09;&#xff0c;这时候就需要我们自己去从手机安装包中提取手表安装包了 准备材料 下载软件mt管理器&#xff08;可自行寻找或直接下载本文附…

三星s2刷android wear,好过安卓手表?三星 Gear S2 上手体验

三星已经连续推出多款智能手表&#xff0c;现在终于拿出了一款像样的智能手表。由于配备了最新的 TLC 闪存&#xff0c;这是目前为止三星最好的一款智能手表。 可能从苹果手表的数码皇冠中获得了灵感&#xff0c;Gear S2能让你不仅可以通过触摸屏&#xff0c;也能通过旋转表圈来…

android wear ios 连接,教你如何让Android Wear智能手表兼容iOS系统

也许未来Android Wear系统智能手表有可能官方兼容iOS系统&#xff0c;但是想要等到这一天&#xff0c;似乎还得有点耐心。因此如果你恰好是一位iPhone用户&#xff0c;同时又不太喜欢Apple Watch&#xff0c;购买了一款Android Wear系统智能手表&#xff0c;那么现在已经有方法…

wear os 自制安卓智能手表音乐播放器

界面展示 设计 使用google MediaSession框架&#xff0c;完全兼容安卓设备 播放整体流程 应用架构 功能 播放/暂停上一曲/下一曲音乐列表音量调节进度条展示播放信息展示后台唤醒扫描本地音乐耳机控制播放其他声音自动暂停断开蓝牙自动暂停 代码地址 github GitHub - isxcwen…