//仅仅是构造一个线程类,但没有和具体化的线程函数关联
thread() noexcept;
// 移动构造函数
thread( thread&& other ) noexcept;
//构造新的 std::thread 对象并将它与执行线程关联
template< class Function, class... Args >
explicit thread( Function&& f, Args&&... args );
上面就是C++11线程构造函数 。第三个构造函数是一个可以传入多个参数的模板函数,也就是说传给线程的执行函数的参数可以有任意多个。
其中f是任意一个可调用对象,包括普通函数、函数对象 、lambda表达式等,args是传递给线程函数的参数。
需要特别注意的是,传到线程函数的参数默认是按值传递或者被移动的,若需要传递引用参数给线程函数,则必须包装它(例如用 std::ref 或 std::cref )。
如下:
void pause_thread(int nSleepTime, int x, int y)
{
//std::cout << "pause for: " << nSleepTime << "\n";
std::this_thread::sleep_for(std::chrono::seconds(nSleepTime));
}
int main()
{
std::thread thread1(pause_thread, 1, 3, 4);
}
此时 nSleepTime参数为1, x为3, y为4,必须注意的是:传入的参数个数必须和线程的执行函数的参数个数相同,类型相同或可以转化为同类型,否则编译会报错。
//代码清单 1
//函数对象
class background_task
{
public:
background_task(int number, char* pszName) :
m_nNumber(number),
m_pszName(pszName){}
~background_task(){}
void operator()() const
{
std::this_thread::sleep_for(std::chrono::seconds(2));
//分离式情况下,m_pszName是非法指针
std::cout << "number is: " << m_nNumber << " name is: " << m_pszName << std::endl;
}
private:
int m_nNumber;
std::string m_strName;
char* m_pszName;
};
// t1 非线程
std::thread t1;
//使用普通函数进行构造线程,按值传递
void f1(int n){std::cout << n << std::endl;}
std::thread t2(f1, 10);
//使用函数对象构造线程,使用引用
background_task task(12, "jimmy");
std::thread run_task(std::ref(task));