是否可以多线程同时执行非 void 函数? (C++)
Posted
技术标签:
【中文标题】是否可以多线程同时执行非 void 函数? (C++)【英文标题】:Is it possible to multithread to execute non-void functions at the same time? (C++) 【发布时间】:2017-08-20 21:34:50 【问题描述】:假设我有一个函数,它对一个向量进行对数变换,乘以一个常数,因此我定义了一个映射函数,给定向量和常数......
vector<double> logtransform(vector<double> &data, int constant)
vector<double> image;
for (int i = 0; i < data.size(); i++)
image.push_back(constant*log(data[i]));
return image;
给定一个名为“data”的向量,我需要对包含在双精度数组中的不同数量的常量应用“logtransform”函数,但是如果函数不是void类型吗?
【问题讨论】:
类型与什么有什么关系? 首先,你应该在向量中至少有reserve
data.size() 元素。这里最好将向量resize
,然后只需将转换后的值分配给向量中的每个位置。这现在可以并行化(使用 OpenMP 或实际创建一个辅助函数来进行就地转换。
在多线程中执行此函数时,您遇到的具体问题是什么?
您可能更愿意剖析您的 for()
循环以由多个内核并行执行,每个内核负责计算 log[data]
的特定范围。
【参考方案1】:
使用标准库。从std::transform
开始并让它工作:
std::vector<double> image(data.size()); // allocate all elements!
std::transform(data.begin(), data.end(), image.begin(),
[](double val) return constant*log(val); );
我认为是对的,但我没有测试过。
一旦你让它工作,并行化它:
std::vector<double> image(data.size()); // allocate all elements!
std::transform(std::execution::par,
data.begin(), data.end(), image.begin(),
[](double val) return constant*log(val); );
并行化它的唯一变化是添加新的第一个参数std::execution::par
。这需要 C++17。
【讨论】:
我对 C++17 不太熟悉,也没学过 execution::par,但看起来很有希望。【参考方案2】:当其他线程准备好时,您可以使用std::future 从其他线程收集结果,如下所示:
std::vector<double> logtransform(std::vector<double> const& data, int constant)
std::vector<double> image;
image.reserve(data.size());
std::transform(std::begin(data), std::end(data), std::back_inserter(image),
[constant](double d) return constant * std::log(d); );
return image;
int main()
std::vector<double> data = 0.3, 0.7, 0.9;
// start a thread to do the transform
// remember to pass data by reference using std::cref() (constant reference)
auto future = std::async(std::launch::async, logtransform, std::cref(data), 5);
// do something else in parallel
for(auto i = 0; i < 10; ++i)
std::cout << " " << i;
std::cout << '\n';
// collect results
auto results = future.get(); // will wait if thread not finished
for(auto d: results)
std::cout << " " << d;
std::cout << '\n';
注意:需要C++11
函数std::async 启动一个线程来完成这项工作并返回一个std::future,您可以使用它稍后获取结果。
【讨论】:
哇很好的答案。顺便说一句,是否有必要“并行做其他事情”?是否有必要将 for 循环从 0 打印到 9? @MikeChen for 循环只是一个例子。如果您不打算在当前线程中同时进行其他工作,那么创建新线程是没有意义的。该循环就是此类工作的一个示例。以上是关于是否可以多线程同时执行非 void 函数? (C++)的主要内容,如果未能解决你的问题,请参考以下文章