头文件:#include <thread>
启动线程:
1.函数参数:
1 void do_work(); 2 std::thread t(do_work);
2.对象参数:
1 class do_work {
2 public:
3 void operator()();
4 };
5 do_work dw;
6 std::thread t(dw);
注意这里只是传了一个对象的拷贝进去。如果想传递对象本身(你应该确保在线程结束前它没有被销毁),可以使用std::ref。
do_work dw;
std::thread t(std::ref(dw));
很多创建线程的API允许传递一个参数给线程,例如long或void*。Std::thread也支持参数,并且可以是任意类型任意个数的参数。
void do_more_work(int i,std::string s,std::vector<double> v);
std::thread t(do_more_work,42,"hello",std::vector<double>(23,3.141));
也可以用std::ref传引用。
1 void foo(std::string&);
2 std::string s;
3 std::thread t(foo,std::ref(s));
结束线程:
新标准中有个术语叫joining来表示与线程协同工作, 使用成员函数join()来阻塞主线程,等待子线程执行结束。
void do_work();
std::thread t(do_work);
t.join();
若不想joining你的线程,可以销毁线程对象或者调用detach()。
1 void do_work();
2 std::thread t(do_work);
3 t.detach();
注意:
若程序中既没使用join(),结尾也没调用detach(),则会在主线程执行结束时报错:
terminate called without an active exception
Aborted
报告pure virtual method called terminate called without an active exception,从网上搜索了一下,前人说这个问题是因为我们析构一个还在使用中的对象,这个绝对是多线程未能正确同步造成的,一个线程还在使用一个对象,而别一个线程开始清理这个对象。多数情况下,程序崩溃只有一个段错误的提示,不会给出上面这个提示,因此调试也比较困难。