线程传参,detach的大坑,成员函数做线程函数

传递临时对象作为参数

VS shitf+F9
查看变量

void myprint(const int &t, char *j)
{
	cout << t << endl;
	cout << j << endl;

}

int main()
{
	int m=1;
	int &n = m;
	char mybuf[] = "hello world";

	std::thread mythred(myprint, n, mybuf);
	//mythred.join();
	mythred.detach();
    return 0;
}

指针在detach中绝对有问题,传引用也是传的复制。

class A {
public:
	A() { cout << "构造函数执行" << endl; }
	~A() { cout << "析构函数执行" << endl;  }
	A(const A &b) { cout << "拷贝构造函数执行" << endl; }
};
void myprint(int i, const A &a)
{
	cout << i << endl;
	cout << &a << endl;
}
int main()
{
	int m=1;
	int &n = m;
	A a;
	std::thread mythred(myprint, n, a);
	mythred.detach();
    return 0;
}

在这里插入图片描述

其中,传已有变量的时候,A的析构函数只执行了一次。

class A {
public:
	A() { cout << "构造函数执行" << endl; }
	~A() { cout << "析构函数执行" << endl;  }
	A(const A &b) { cout << "拷贝构造函数执行" << endl; }
};
void myprint(int i, const A &a)
{
	cout << i << endl;
	cout << &a << endl;
}
int main()
{
	int m=1;
	std::thread mythred(myprint, m, A(a));
	mythred.detach();
    return 0;
}

在这里插入图片描述
所以,要传对象得使用临时对象。因为临时对象是在主线程中创建的。

(1)若传的是简单参数,直接值传递,不要用引用。
(2)如果传递的是类对象,避免隐式类型转换。然后在函数参数里面,采用引用传参,否则,还会多一次拷贝构造。
所以,detach()有什么好。

线程ID:get.id()

class A {
public:
	mutable int i;
	A(int j):i(j) { cout <<"i="<<i<< "构造函数执行" << "ID=" << std::this_thread::get_id() << endl; }
	~A() { cout << "析构函数执行" << endl;  }
	A(const A &b):i(b.i) { cout << "i=" << i << "拷贝构造函数执行" << "ID=" << std::this_thread::get_id() << endl; }
};
void myprint( const A &a)
{
	a.i = 100;
	cout <<"\t\tID="<<std::this_thread::get_id()<< endl;
}
int main()
{
	A a(10);
	std::thread test(myprint, a);
	test.join();
    return 0;
}

即时传入的是引用,但是也不会修改源对象的值,因为修改的地址不同,为了数据的安全考虑,往线程传递类类型,编译器会统一按照拷贝的方式。

std::ref :传递对象,而不是拷贝。

class A {
public:
	mutable int i;
	A(int j):i(j) { cout <<"i="<<i<< "构造函数执行" << "ID=" << std::this_thread::get_id() << endl; }
	~A() { cout << "析构函数执行" << endl;  }
	A(const A &b):i(b.i) { cout << "i=" << i << "拷贝构造函数执行" << "ID=" << std::this_thread::get_id() << endl; }
};
void myprint(A &a)
{
	a.i = 100;
	cout <<"\t\tID="<<std::this_thread::get_id()<< endl;
}
int main()
{
	A a(10);
	std::thread test(myprint, std::ref(a));
	test.join();
    return 0;
}

在这里插入图片描述

std::move() 智能指针在线程中的传递

class A {
public:
	mutable int i;
	A(int j):i(j) { cout <<"i="<<i<< "构造函数执行" << "ID=" << std::this_thread::get_id() << endl; }
	~A() { cout << "析构函数执行" << endl;  }
	A(const A &b):i(b.i) { cout << "i=" << i << "拷贝构造函数执行" << "ID=" << std::this_thread::get_id() << endl; }
};
void myprint(unique_ptr<A>a)
{
	a->i = 100;
	cout <<"\t\tID="<<std::this_thread::get_id()<< endl;
}
int main()
{
	unique_ptr<A> a(new A(10));
	std::thread test(myprint, std::move(a));
	test.join();
    return 0;
}

而且绝对不能detach()。

用成员函数作为线程函数。

猜你喜欢

转载自blog.csdn.net/a12345d132/article/details/84324374