C++11 多线程
1. 线程的创建
使用线程函数或者函数对象,并且可以同时制定线程函数的参数
#include<thread> void func(){/*do something*/} int main() { std::thread t(func); t.join();//阻塞线程,直到函数执行结束 //t.detach(); 将线程和线程对象分离 return 0; }
函数func将会运行于线程对象t中,join函数将会阻塞线程,直到线程函数执行结束,如果线程函数由返回值,返回值将会被忽略。如果不希望线程被阻塞执行,可以调用线程的detach()方法,将线程和线程对象分离,让线程作为后台线程去执行。 detach之后就无法再和线程发生联系了。主进程结束的时候,即便是detach()出去的子线程不管有没有完成都会被强制杀死
线程还可以接收任意个数的参数
void func(int i,double d,const std::string& s) { std::cout<<i<<","<<d<<","<<s<<std::endl; } int main() { std::thread t(func,1,2,"test"); t.join(); return 0; }
注意:std::thread 出了作用域之后将会析构,如果线程函数没有执行完将会发生错误,因此,需要保证线程函数的生命周期在线程变量std::thread的生命周期之内。
线程不能复制,但是可以移动
#include<thread> void func(){/*do something*/} int main() { std::thread t(func); std::thread t1(std::move(t)); t.join(); t2.join(); return 0; }
通过将线程对象保存到一个容器中,以保证线程对象的生命周期。
由于线程对象可能先于线程函数结束,所以应该保证线程对象的生命周期在线程函数执行完时仍然存在。可以通过join阻塞等待线程函数执行完成,或者通过detach方法让程序在后台执行,还可以通过将线程对象保存到一个容器中,以保证线程对象的生命周期。
std::vector<std::thread> g_list; std::vector<std::shared_ptr<std::thread>> g_list2; void CreateThread() { std::thread t(func); g_list.push_back(std::move(t)); g_list2.push_back(std::make_shared<std::thread>(func)); } int main() { CreateThread(); for(auto& thread:g_list) { thread.join; } for(auto& thread:g_list2) { thread->join(); } return 0; }
2. 线程的基本用法
获取当前信息
线程可以获取当前线程的ID,还可以获取CPU核心数量
void fun(){/*do something*/} int main() { std::thread t(func); cout<<t.get_id()<<endl;//获取当前线程ID //获取当前CPU核数,如果获取失败则返回0 cout<<std::thread::hardware_concurrency()<<endl; return 0; }
线程休眠
std::this_thread::sleep_for(std::chrono::seconds(3));//线程休眠3秒
声明:以上主要来源于深入应用C++11 这本书,强烈推荐