C++11多线程02
#include <iostream> #include <thread> void thread_fun() { std::cout<<"我是线程函数"<<std::endl; } int main() { std::thread t(thread_fun); try //这样写有利于无论主线程是否出问题,都可以调用join()启动子线程 { for(int i=0 ; i< 100 ;i++) { std::cout<<"主线程:"<<i<<std::endl; } }catch(...) //捕获任何异常 { t.join(); throw ; } t.join(); return 0; }

下面使用类来初始化线程
#include <iostream> #include <thread> class Factor { public : void operator() () { for(int i=0 ; i>-100 ; i--) { std::cout<<"子线程:"<<i<<std::endl; } } }; int main() { Factor fac ; std::thread t(fac); try //这样写有利于无论主线程是否出问题,都可以调用join()启动子线程 { for(int i=0 ; i< 100 ;i++) { std::cout<<"主线程:"<<i<<std::endl; } }catch(...) //捕获任何异常 { t.join(); throw ; } t.join(); return 0; }

上面例子也可以稍作修改
Factor fac ;
std::thread t(fac);
替换为
std::thread t((Factor()));
完整如下:
#include <iostream> #include <thread> class Factor { public : void operator() () { for(int i=0 ; i>-100 ; i--) { std::cout<<"子线程:"<<i<<std::endl; } } }; int main() { std::thread t((Factor())); try //这样写有利于无论主线程是否出问题,都可以调用join()启动子线程 { for(int i=0 ; i< 100 ;i++) { std::cout<<"主线程:"<<i<<std::endl; } }catch(...) //捕获任何异常 { t.join(); throw ; } t.join(); return 0; }

下面介绍如何传入参数
#include <iostream> #include <thread> #include <string> class Factor { public : void operator() (std::string msg) { for(int i=0 ; i>-100 ; i--) { std::cout<<"子线程:"<<i<<" "<<msg<<std::endl; } } }; int main() { std::string msg = "C++是中国的"; std::thread t((Factor()),msg); try //这样写有利于无论主线程是否出问题,都可以调用join()启动子线程 { for(int i=0 ; i< 100 ;i++) { std::cout<<"主线程:"<<i<<std::endl; } }catch(...) //捕获任何异常 { t.join(); throw ; } t.join(); return 0; }

性能优化:传入引用
#include <iostream> #include <thread> #include <string> class Factor { public : void operator() (std::string& msg) { std::cout<<"子线程:"<<msg<<std::endl; msg = "C++是日本的"; } }; int main() { std::string s = "C++是中国的"; std::thread t((Factor()),std::ref(s)); //std::thread t((Factor()),s);在MSVC2013中可以运行,GCC中不行 //在MSVC2013中,可以看出,即使void operator() (std::string& msg), //std::thread t((Factor()),s)传入的仍然是拷贝,最后的s没有改变 t.join(); std::cout<<"s:"<<s<<std::endl; return 0; }
在MSVC2013中,也可以使用std::move(),但是在GCC中不行

切记在C++中有些对象不能够被复制,但能被移动
#include <iostream> #include <thread> #include <string> class Factor { public : void operator() (std::string& msg) { std::cout<<"子线程:"<<msg<<std::endl; msg = "C++是日本的"; } }; int main() { std::string s = "C++是中国的"; std::thread t((Factor()),std::ref(s)); //t.join(); 这里不能使用了,待会儿move之后,t就是个空壳了 //std::thread t2 = t ; std::thread是不能复制的 std::thread t2 = std::move(t) ; t2.join(); std::cout<<"s:"<<s<<std::endl; return 0; }

下面获取线程ID
#include <iostream> #include <thread> #include <string> class Factor { public : void operator() (std::string& msg) { std::cout<<"子线程:"<<msg<<std::endl; msg = "C++是日本的"; } }; int main() { std::cout<<"主线程ID:"<<std::this_thread::get_id()<<std::endl; std::string s = "C++是中国的"; std::thread t((Factor()),std::ref(s)); std::thread t2 = std::move(t) ; std::cout<<"子线程ID:"<<t2.get_id()<<std::endl; t2.join(); std::cout<<"s:"<<s<<std::endl; return 0; }

下面获取本电脑并发执行的最大线程数
#include <iostream> #include <thread> #include <string> class Factor { public : void operator() (std::string& msg) { std::cout<<"子线程:"<<msg<<std::endl; msg = "C++是日本的"; } }; int main() { std::cout<<"本电脑可以并发执行的最大线程数:"<<std::thread::hardware_concurrency()<<std::endl; std::cout<<"主线程ID:"<<std::this_thread::get_id()<<std::endl; std::string s = "C++是中国的"; std::thread t((Factor()),std::ref(s)); std::thread t2 = std::move(t) ; std::cout<<"子线程ID:"<<t2.get_id()<<std::endl; t2.join(); std::cout<<"s:"<<s<<std::endl; return 0; }


浙公网安备 33010602011771号