启动线程
thread类的构造函数接收一个可调用的类型。可调用的类型,除了函数,还可以是函数对象和lamda表达式。
class foo{
public:
void operator() (){
for(int i = 0 ; i < 5; i++)
std::cout << "foo concurrent \n";
}
};
void fun(){
for(int i = 0 ; i < 5; i++)
std::cout << "lamda concurrent \n";
}
int main()
{
using std::thread;
foo my_foo;
thread t1(my_foo); //函数对象
thread t2(fun); //函数
thread t3([]{fun();});//lamda表达式
t1.join();
t2.join();
t3.join();
}
注意:在传入函数对象时,不能直接传入临时变量,这会引起c++语法解析错误(c++'s most vexing parse):
thread t2(foo());
foo()返回一个临时变量。对于上述代码,编译器会解析为返回thread类名为t2的函数,而不是创建一个线程。在传入函数对象时,我们除了创建一个非临时变量(如同最上方代码那样),还可以使用如下两种方式:
thread t4((foo()));
thread t5{foo()};
注意,t4的foo()外层还有一层()。
使用join()函数阻塞当前线程
当我们在当前线程中,创建一个新的线程。父线程结束时,会回收自己的资源,但并不会理会子线程是否结束,并强行调用线程的析构函数,此时会报terminate called without an active exception。
clas