要将参数传递给线程的可关联对象或函数,只需将参数传递给std::thread构造函数。
默认情况下,所有的参数都将复制到新线程的内部存储中。
看一个例子:给线程传递单个参数
#include <iostream>
#include <string>
#include <thread>
void threadCallback(int x, std::string str) {
std::cout << "Passed Number = " << x << std::endl;
std::cout << "Passed String = " << str << std::endl;
}
int main() {
int x = 10;
std::string str = "Sample String";
std::thread threadObj(threadCallback, x, str);
threadObj.join();
return 0;
}
怎样给线程传递函数
不要将本地堆栈变量的地址传递给线程的回调函数,因为线程1中的局部变量可能会超出范围,但线程2仍然尝试通过它的地址访问它。
在这种情况下,访问无效地址可能会导致不可预测的行为。
例如:
#include <iostream>
#include <thread>
void newThreadCallback(int* p) {
std::cout << "Inside Thread : "" : p = " << *p << std::endl;
std::chrono::milliseconds dura(1000);
std::this_thread::sleep_for(dura);
*p = 19;
}
void startNewThread() {
int i = 10;
std::cout << "Inside Main Thread : "" : i = " << i << std::endl;
std::thread t(newThreadCallback, &i);
t.detach();
std::cout << "Inside Main Thread : "" : i = " << i << std::endl;
}
int main() {
startNewThread();
std::chrono::milliseconds dura(2000);
std::this_thread::sleep_for(dura);
return 0;
}
同样的,在将指针传递给位于heap上的线程时,要小心,因为某些线程可能在新线程尝试访问它之前删除该内存。
在这种情况下,访问无效地址可能会导致不可预测的行为。
例如:
#include <iostream>
#include <thread>
void newThreadCallback(int* p) {
std::cout << "Inside Thread : "" : p = " << *p << std::endl;
std::chrono::milliseconds dura(1000);
std::this_thread::sleep_for(dura);
*p = 19;
}
void startNewThread() {
int* p = new int();
*p = 10;
std::cout << "Inside Main Thread : "" : *p = " << *p << std::endl;
std::thread t(newThreadCallback, p);
t.detach();
delete p;
p = NULL;
}
int main() {
startNewThread();
std::chrono::milliseconds dura(2000);
std::this_thread::sleep_for(dura);
return 0;
}
给线程传递引用
由于参数被复制到新的线程堆栈,所以,如果想通过常用的方式传递引用,如:
#include <iostream>
#include <thread>
void threadCallback(int const& x) {
int& y = const_cast<int&>(x);
y++;
std::cout << "Inside Thread x = " << x << std::endl;
}
int main() {
int x = 9;
std::cout << "In Main Thread : Before Thread Start x = " << x << std::endl;
std::thread threadObj(threadCallback, x);
threadObj.join();
std::cout << "In Main Thread : After Thread Joins x = " << x << std::endl;
return 0;
}
输出为:
In Main Thread : Before Thread Start x = 9Inside Thread x = 10
In Main Thread : After Thread Joins x = 9
即使threadCallback接受参数作为引用,但是并没有改变main中x的值,在线程引用外它是不可见的。
这是因为线程函数threadCallback中的x是引用复制在新线程的堆栈中的临时值。
使用 std::ref
#include <iostream>
#include <thread>
void threadCallback(int const& x) {
int& y = const_cast<int&>(x);
y++;
std::cout << "Inside Thread x = " << x << std::endl;
}
int main() {
int x = 9;
std::cout << "In Main Thread : Before Thread Start x = " << x << std::endl;
std::thread threadObj(threadCallback, std::ref(x));
threadObj.join();
std::cout << "In Main Thread : After Thread Joins x = " << x << std::endl;
return 0;
}
输出:
In Main Thread : Before Thread Start x = 9
Inside Thread x = 10
In Main Thread : After Thread Joins x = 10
指定一个类的成员函数的指针作为线程函数
将指针传递给成员函数作为回调函数,并将指针指向对象作为第二个参数
#include <iostream>
#include <thread>
class DummyClass {
public:
DummyClass() { }
DummyClass(const DummyClass& obj) { }
void sampleMemberfunction(int x) {
std::cout << "Inside sampleMemberfunction " << x << std::endl;
}
};
int main() {
DummyClass dummyObj;
int x = 10;
std::thread threadObj(&DummyClass::sampleMemberfunction, &dummyObj, x);
threadObj.join();
return 0;
}