【c++】std::thread 传参问题

1.向std::thread 构造函数传参:所有参数均按值并以副本的形式保存在std::thread对象中的tuple里。这一点的实现类似于std::bind。如果要达到按引用传参的效果,可使用std::ref来传递。

代码1:普通方式

void mytest::funtest(int aa, int bb)
{
    //emit signaltest();

    int aa1 =0;
    aa1++;

}

使用:
void mytest::start()
{
    int aa = 10;
    int bb = 10;

    std::thread(&mytest::funtest, this, aa, bb).detach();

}

代码2:std::ref方式

void mytest::funtest(int &aa, int &bb)
{
    emit signaltest();

    int aa1 =0;
    aa1++;

}

使用:
int aa = 10;
int bb = 10;

void mytest::start()
{

    std::thread(&mytest::funtest, this, std::ref(aa), std::ref(bb)).detach();

}

2.线程函数的形参通常为T、const T&或T&&类型,如果源类型是指针或引用类型时,要防止可能发生悬空指针和悬空引用的现象,因此需要手动管理参数的生命周期

错误代码:

void mytest::start()
{
    int aa = 10;
    int bb = 10;

    std::thread(&mytest::funtest, this, std::ref(aa), std::ref(bb)).detach();

}

void mytest::funtest(int &aa, int &bb)
{
    emit signaltest();

    int aa1 =0;
    aa1++;

}

这里的aa,bb实际上是 不对的,因为start函数执行完,就销毁掉了,正确的做法是修改为类的成员变量,或者全局变量,或者使用new生成的

小结:

1.一个实参从主线程传递到子线程的线程函数中,需要经过两次传递。第1次发生在std::thread构造时,此次参数按值并以副本形式被保存。第2次发生在向线程函数传递时,此次传递是由子线程发起,并将之前std::thread内部保存的副本以右值的形式(std::move())传入线程函数中的。

2.如果线程函数的形参为T、const T&或T&&类型时,std::thread的构造函数可以接受左值或右值实参。因为不管是左值还是右值,在std::thread中均是以副本形式被保存,并在第2次向线程函数传参时以右值方式传入,而以上三种形参均可接受右值。

3.如果线程函数的形参为T&时,需要手动管理参数的生命周期,防止出现悬空指针和悬空引用的现象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kevin--你不知道的事

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值