gpt4 book ai didi

c++ - 将 std::async 与需要函数和参数参数的函数一起使用

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:14:42 25 4
gpt4 key购买 nike

我正在研究多线程 C++ vapply 函数,它将函数应用于 vector 的每个元素。诀窍是我不想为 vector 中的每个元素创建一个线程;我宁愿创建一定数量的线程,并为每个线程分配一个要处理的 vector 。

但是,我不确定如何使用 std::async 捕获操作结果。这是我到目前为止所拥有的:

vapply.h:

#ifndef VAPPLY_H
#define VAPPLY_H

#include <vector>
#include <thread>
#include <memory>
#include <future>
#include <functional>

class vapply
{
private:
template <class Fn, class T>
auto docall(Fn&& fn, std::vector <T> &v, size_t begin, size_t end)
{
using return_type = typename std::result_of <Fn(T)>::type;
std::vector <return_type> result;
result.reserve(end - begin);
for (size_t i = begin; i < end; i++)
{
result.emplace_back(fn(v[i]));
}
return result;
}
public:
// Constructor
template <class Fn, class T>
vapply(Fn&& fn, std::vector <T> &v)
{
size_t maxNumThreads = std::thread::hardware_concurrency() - 1;
size_t funcPerThread = v.size() / maxNumThreads;
size_t funcModThread = v.size() % maxNumThreads;

size_t funcToPerform = 0;
for (size_t i = 0; i < v.size(); i += funcToPerform)
{
funcToPerform = (i == 0) ? funcPerThread + funcModThread : funcPerThread;
// this line works fine, extract the results of docall
auto p = docall(std::forward <Fn>(fn), v, i, i + funcToPerform);
// now I'd like to do the same thing but in a separate thread, but below doesn't compile
// auto q = std::async(std::launch::async, &vapply::docall, std::forward <Fn>(fn), v, i, i + funcToPerform);
}
}
};

#endif /* VAPPLY_H */

main.cpp:

#include <iostream>
#include <numeric>
#include <string>

#include "vapply.h"

std::string test1(uint64_t a)
{
return std::to_string(a);
}

int main(int argc, char **argv)
{
std::vector <uint64_t> v(17);
std::iota(v.begin(), v.end(), 0);
vapply(test1, v);
return 0;
}

最佳答案

auto q = std::async(std::launch::async, &vapply::docall, std::forward <Fn>(fn), v, i, i + funcToPerform);此行无法编译,因为要将方法作为参数传递给函数,它必须绑定(bind)到一个实例,this在这种情况下。所以使用 std::bind或者更好的像这样的 lambda:auto fut = std::async(std::launch::async, [&] { return docall(std::forward <Fn>(fn), v, i, i + funcToPerform); });得到 future 的结果使用它的 get()像这样的方法 auto q = fut.get();但请记住future::get()是阻塞调用所以调用 async()然后 future::get()在一个循环中不会运行多个线程。而是将 future 保存在一个循环中,然后在另一个循环中为每个 future 调用 get()。

关于c++ - 将 std::async 与需要函数和参数参数的函数一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35367774/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com