【C++新经典】【并发与多线程】3 线程传参详解、detach坑与成员函数作为线程函数


传递临时对象

#include <iostream>
#include <thread>
using namespace std;

class A {
public:
    A(int a) : m_i(a) { cout << "构造函数 " << this << endl; }
    A(const A &a) { cout << "拷贝构造 " << this << endl; }
    ~A() { cout << "析构函数 " << this << endl; }
private:
    int m_i;
};

void SubThreadFunc(const int i, const A& tmp_buf) {
    cout << i << endl;
    cout << &tmp_buf << endl;
}

int main() {
    int param1 = 1;
    int param2 = 12;

    thread my_thread(SubThreadFunc, param1, A(param2));
    // my_thread.join();
    my_thread.detach();

    return 0;
}

(base) localhost:~/Desktop$ ./main
构造函数 0x7ffee4388680
拷贝构造 0x7ffee43885d0
拷贝构造 0x7fc988c00684
析构函数 0x7ffee43885d0
析构函数 0x7ffee4388680
1
0x7fc988c00684
析构函数 0x7fc988c00684
  • 形参 i 即使加了引用,也是值传递。
  • 如果传递类对象作为参数,则避免隐式类型转换。
  • 上述 A 执行了一次构造,两次拷贝构造。子线程中打印的地址是第二次拷贝构造的对象的地址。
#include <iostream>
#include <thread>

using namespace std;

class A {
public:
	A(int a) : m_i(a) { cout << "构造函数 " << this << endl; }
	A(const A &a) { cout << "拷贝构造 " << this << endl; }
	~A() { cout << "析构函数 " << this << endl; }
private:
	int m_i;
};

void SubThreadFunc(const int i, const A& tmp_buf) {
	cout << i << endl;
    cout << &tmp_buf << endl;
}

int main() {
	int param1 = 1;
	int param2 = 12;

	SubThreadFunc(param1, A(param2));

	return 0;
}

(base) localhost:~/Desktop$ ./main
构造函数 0x7ffee0d6c690
1
0x7ffee0d6c690
析构函数 0x7ffee0d6c690

作为对比,如果是函数调用,只有一次构造过程。

传递类对象

#include <iostream>
#include <thread>

using namespace std;

class A {
public:
    mutable int m_i;
    A(int i) : m_i(i) {}
};

void subThreadFunc(const A& a) {
    a.m_i = 199;
    cout << "sub thread address a:" << &a << " thread id = " << std::this_thread::get_id() << endl;
}

int main() {
    A myObj(10);

    //如果希望子线程中修改m_i的值影响到主线程,可以用thread my_thread(subThreadFunc, std::ref(myObj));
    thread my_thread(subThreadFunc, myObj);
    my_thread.join();

    cout << "Hello World!" << endl;

    return 0;
}

传递智能指针

#include <iostream>
#include <thread>
#include <memory>

using namespace std;

void subThreadFunc(unique_ptr<int> ptr) {
    cout << "in sub: " << ptr << endl;
}

int main() {
    unique_ptr<int> ptr(new int(10));

    cout << "before sub: " << ptr << endl;

    // 独占式指针只能通过 std::move() 才可以传递给另一个指针
    // 传递后 ptr 就指向空,新的 ptr 指向原来的内存
    // 所以这时就不能用 detach 了,因为如果主线程先执行完,ptr 指向的对象就被释放了
    thread my_thread(subThreadFunc, std::move(ptr));
    my_thread.join();

    cout << "after sub: " << ptr << endl;

    return 0;
}

(base) ~/Desktop$ ./main
before sub: 0x7f9189400600
in sub: 0x7f9189400600
after sub: 0x0

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值