C++ 并行编程《一》
Posted ppwei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++ 并行编程《一》相关的知识,希望对你有一定的参考价值。
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被销毁时,会等待子线程结束 */
以上是关于C++ 并行编程《一》的主要内容,如果未能解决你的问题,请参考以下文章
虚幻4与现代C++:基于任务的并行编程与TaskGraph入门