翻译来自:C++11 Multithreading – Part 3: Carefully Pass Arguments to Threads
要将参数传递给线程的关联可调用对象或函数,只需将其他参数传递给std :: thread构造函数。
默认情况下,所有参数都复制到新线程的内部存储中。
让我们看一个例子
在C ++ 11中将简单参数传递给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;
}
如何不将参数传递给C ++ 11中的线程
不要将变量的地址从本地堆栈传递到线程的回调函数。因为线程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;
}
同样,在将指针传递给堆上位于线程的内存时要小心。因为某些线程可能会在新线程尝试访问该内存之前删除该内存。
在这种情况下,访问无效地址可能会导致意外行为。
例如,
#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;
}
如何在C ++ 11中传递对std :: thread的引用
由于参数被复制到新的线程堆栈,因此,如果您需要以通用方式传递引用,即
检查一下:
#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 = 9
Inside Thread x = 10
In Main Thread : After Thread Joins x = 9
即使threadCallback接受参数作为引用,但所做的更改仍在线程外部不可见。
这是因为线程函数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;
}
Its output is
In Main Thread : Before Thread Start x = 9
Inside Thread x = 10
In Main Thread : After Thread Joins x = 10
将指向类的成员函数的指针分配为线程函数:
将指针传递给成员函数作为回调函数,并将指针传递给Object作为第二个参数。
例如,
#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;
}