栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

线程传参详解、detach()大坑、成员函数做线程函数

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

线程传参详解、detach()大坑、成员函数做线程函数

#include 
#include 

using namespace std;

void myprint(const int& i,char* pmybuf)
{
    printf("&i=%pn",&i); // i 虽然是引用,但是是值拷贝
    cout< 

detach()的时候,参数一定不能传指针,最好不要传引用,虽然引用是值拷贝的方式进行传递。

#include 
#include 

using namespace std;


class A
{
    public:
      int m_i;
      A(int a):m_i(a) {cout<<"A::A(int a) constructor is doing..."< 

总结:

1.如果传递int等简单类型,建议都是值传递,不要用应用,防止节外生枝。

2.如果传递类对象,避免隐士类型转化。全部都在创建线程这一行就构建出临时对象来,然后在函数参数里,用引用来接,否则系统还会构造出一次对象出来,避免浪费资源。

3.终极结论,建议不适用detach(),只使用join(),这样就不存在局部变量失效导致线程对内存的非法引用问题。除法万不得已,不要使用detach().

二、临时对象作为线程参数继续讲,用测试大法

1.为什么构造临时对象就安全了?探索根本原因,知其然,而知其所以然。

2.1 线程id,每个线程实际上都对应的是一个数字,不同的线程所对应的数字肯定是不一样的,线程id通过std::this_thread::get_id()来获取。

#include 
#include 

using namespace std;


class A
{
    public:
      int m_i;
      A(int a):m_i(a) {cout<<"A::A(int a) constructor is doing,this="< 

thread myobj(myprint2,mvar);  //这种方式是在子线程中构造A对象,如果用detach(),会出现致命的问题。

thread myobj(myprint2,A(mvar));这种方式是在主线程中构造A对象,如果用detach(),就不会出现致命的问题。

三:传递类对象,智能指针作为线程参数

std::ref 函数 诞生的原因:

在多线程编程中,主线程和辅线程在进行参数传递的时候,不管是进行值传递,还是引用传递,编译器为了数据安全都是进行拷贝一份。那么这样其实就违背了引用的正常语义了,那么std::ref 函数就诞生了。

#include 
#include 

using namespace std;


class A
{
    public:
      mutable int m_i;
      A(int a):m_i(a) {cout<<"A::A(int a) constructor is doing,this="<
#include 

using namespace std;


class A
{
    public:
       int m_i;
      A(int a):m_i(a) {cout<<"A::A(int a) constructor is doing,this="< 

用了std::ref 之后,用引用进行参数传递的时候,就符合了引用的本来的语义了。

线程中传递智能指针写法:

#include 
#include 

using namespace std;


class A
{
    public:
       int m_i;
      A(int a):m_i(a) {cout<<"A::A(int a) constructor is doing,this="< 

如果不用,std::move(myp) 就会编译不过。

std::move(myp) 表示 独占式智能指针,从主函数的myp对象转移到 子线程函数,中的 unique_ptr pzn,pzn对象中。

四:成员函数指针做线程函数

#include 
#include 

using namespace std;


class A
{
    public:
       int m_i;
      A(int a):m_i(a) {cout<<"A::A(int a) constructor is doing,this="< pzn)
{
    
}


int main(){

    //unique_ptr myp(new int(100));
    //std::thread mytobj(myprint2,std::move(myp));

    //mytobj.join();

    A myobj(10);
    std::thread mytobj(&A::thread_work,myobj,27);
    //std::thread mytobj(&A::thread_work,std::ref(myobj),27);

    mytobj.join();
    
    cout<<"I Love China!"< 

//std::thread mytobj(&A::thread_work,std::ref(myobj),27);  改成这样就不会出现拷贝构造。

//std::thread mytobj(&A::thread_work,&myobj,27); 

std::ref(myobj) 等价写法:&myobj

#include 
#include 

using namespace std;


class A
{
    public:
       int m_i;
      A(int a):m_i(a) {cout<<"A::A(int a) constructor is doing,this="< myp(new int(100));
    //std::thread mytobj(myprint2,std::move(myp));

    //mytobj.join();

    A myobj(10);
    
    thread mytobj(std::ref(myobj),29); // not call copy construct
    //thread mytobj(&myobj,29); //error 

    mytobj.join();
    
    cout<<"I Love China!"< 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/876430.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号