如何正确使用std::async调用模板函数?并行求和代码咨询
正确使用std::async调用你的并行求和模板函数
嘿,你这个并行求和的思路挺靠谱的!先把你没写完的parallel_sum函数补全,再一步步说怎么正确调用它~
首先补全完整的函数实现(把你中断的std::async部分补好):
#include <iostream> #include <future> #include <numeric> #include <type_traits> template<typename T, int N, typename = std::enable_if<std::is_integral<T>::value>::type> T parallel_sum(T(&arr)[N], size_t start = 0, size_t end = N - 1) { // 区间足够小时,直接用std::accumulate串行计算,避免线程开销 if (end - start < 1000) { return std::accumulate(std::begin(arr) + start, std::begin(arr) + end + 1, T{}); // 这里用T{}代替0,是为了适配不同整数类型(比如long long、unsigned int) } else { size_t mid = start + (end - start) / 2; // 用std::async异步启动左半区间的求和任务 // 显式指定std::launch::async强制开新线程,也可以用默认策略让系统自动决定 auto res1 = std::async(std::launch::async, parallel_sum<T, N>, arr, start, mid); // 同步计算右半区间(或者也可以再开一个async,不过这样线程数会翻倍,按需选择) T res2 = parallel_sum(arr, mid + 1, end); // 调用get()等待异步任务完成并获取结果,然后合并 return res1.get() + res2; } }
接下来是正确的调用方式:
1. 最简单的自动推导调用
因为你的模板函数接受数组引用,编译器可以自动推导模板参数T(数组元素类型)和N(数组长度),直接传数组就行:
int main() { // 随便定义一个整数数组,长度任意 int my_arr[] = {1, 2, 3, 4, 5, 6, ..., 10000}; // 直接调用,不用写模板参数,编译器会帮你搞定 int total_sum = parallel_sum(my_arr); std::cout << "数组总和:" << total_sum << std::endl; // 也可以指定部分区间求和,比如只算前500个元素 int partial_sum = parallel_sum(my_arr, 0, 499); std::cout << "前500个元素总和:" << partial_sum << std::endl; return 0; }
2. 显式指定模板参数(可选)
如果你想明确指定模板参数(其实没必要,自动推导更简洁),可以这么写:
// 比如用long long类型的数组 long long big_arr[] = {1LL, 2LL, 3LL, ..., 100000LL}; // 显式指定T=long long,N=数组长度(通过sizeof计算) long long total = parallel_sum<long long, sizeof(big_arr)/sizeof(big_arr[0])>(big_arr);
几个要注意的点
std::launch策略:std::launch::async:强制创建新线程执行任务,适合大区间计算std::launch::deferred:延迟执行,直到调用get()才在当前线程跑,适合小区间- 默认不指定策略的话,系统会根据当前负载自动选择,灵活性更高
std::future的get()方法:调用它会阻塞当前线程,直到异步任务完成,一定要调用,不然异步任务可能不会执行(比如用deferred策略时)- 类型匹配:把初始值从
0改成T{},避免当T是unsigned int或者long long时出现类型不匹配的问题 - 模板约束:你加的
std::enable_if确保只有整数数组能调用这个函数,非整数类型(比如float数组)会直接编译报错,很稳妥
内容的提问来源于stack exchange,提问作者Sajal
相关产品推荐
相关产品推荐

