标签:函数调用 编程 主线程 return 返回 try read err 别名
1.最简单的C++多线程程序
#include <iostream> #include <thread> void do_something() { std::cout << "func do_something..." << std::endl; } int main(int argc, char *argv[]) { std::thread my_thread(do_something); std::cout << "main thread" << std::endl; my_thread.join(); return 0; }
2.在C++标准中,std::thread可以和任何可调用(callable)类型一同工作,所以,我们可以给std::thread构造函数传递一个带有函数调用操作符的类实例,代替直接传入的函数。
#include <iostream> #include <thread> void do_something() { std::cout << "func do_something" << std::endl; } class background_task { public: void operator()() const { do_something(); } }; int main(int argc, char *argv[]) { background_task bt; std::thread my_thread(bt); /* 传入一个类实例 */ std::cout << "main thread" << std::endl; my_thread.join(); return 0; }
3.等待线程结束,C++有两种线程结束的方法(join、detach)。对于detach()方法来讲,即使线程实例被主线程销毁,线程依旧可以后台执行,直到自行结束。
而对于join()方法,主线程会等待子线程的执行,并获得子线程的返回值。问题是,我们在什么地方等待子线程结束,如果发生异常,怎样保证子线程依旧能够正确结束。一种方法如下:
#include <iostream> #include <thread> void do_something() { std::cout << "func do_something..." << std::endl; } class background_task { public: void operator()() { do_something(); } background_task(int val) { std::cout << "background_task constructor init" << std::endl; } }; int main(int argc, char *argv[]) { int init_val = 0; background_task bt(init_val); std::thread my_thread(bt); try { std::cout<<"err occured here"<<std::endl; /* 错误发生位置 */ } catch (...) { my_thread.join(); /* 为了保证线程在异常情况下也能正常结束 */ throw; } my_thread.join(); /* 计划结束位置 */ return 0; }
4.使用try/catch方式结束进程,不仅使代码阅读性降低,而且容易将作用域搞乱,因此需要一种更高明的方法。这样做的方法之一是使用资源获取即初始化(RALL)惯用语法。
如下:
#include <iostream> #include <thread> class thread_guard { std::thread &t; /* 定义一个别名,将传入的线程复制给它 */ public: explicit thread_guard(std::thread &t_) : t(t_) {} ~thread_guard() { /* 将进程结束操作和类资源释放绑定 ,只要类被释放,线程就会结束 */ if (t.joinable()) { t.join(); } } thread_guard(thread_guard const &) = delete; thread_guard &operator=(thread_guard const &) = delete; }; void do_something() { std::cout << "func do_something" << std::endl; } struct func { int &i; func(int &i_) : i(i_) {} void operator()() { do_something(); } }; /* 一个简单明了的,能够保证在异常情况下也能正常结束线程的方法 */ int main(int argc, char *argv[]) { int init_val = 0; func my_func(init_val); std::thread my_thread(my_func); thread_guard g(my_thread); return 0; /* 主线程结束后,会销毁局部变量, 在g被销毁时,会等待子线程结束 */ }
标签:函数调用 编程 主线程 return 返回 try read err 别名
原文地址:https://www.cnblogs.com/PPWEI/p/11422424.html