c++ - ThreadPool 传递函数作为参数
问题描述
我正在尝试实现我自己的并行版本,以使用https://github.com/Fdhvdu/ThreadPool作为后端线程池
我将任务分成几个部分并启动具有以下功能的线程:
template <typename Callable>
void launchRange(int id, Callable func, int k1, int k2)
{
for (int k = k1; k < k2; k++) {
func(k);
}
}
我遇到的问题是如何将它传递Callable
给线程池
相关部分是:
poolPtr->add(launchRange, func, i1, i2);
但我不断收到编译错误。错误是:
...\ithreadpoolitembase.hpp(36): error C2027: use of undefined type 'std::tuple<conditional<_Test,void(__cdecl *&)(int),_Ty>::type,conditional<_Test,int&,int>::type,conditional<_Test,int&,int>::type>'
with
[
_Ty=void (__cdecl *)(int)
]
的接口add
是
template<class Func,class ... Args>
inline thread_id add(Func &&func,Args &&...args);
我正在使用 Visual Studio 2017 Community 15.4/std:c++17
解决方案
launchRange
是函数模板而不是函数。
除非重载决议完成,否则不能将函数模板作为函数传递。该行不会触发重载决议。
auto launchRange = [](int id, auto&& func, int k1, int k2)
{
for (int k = k1; k < k2; k++) {
func(k);
}
};
上面是一个 lambda,它的行为很像launchRange
模板,但它是一个实际的对象,而不仅仅是一个模板。
它仍然不起作用,因为您没有通过add
参数id
。
poolPtr->add(launchRange, 77, func, i1, i2);
那可能会编译。
我不是特别喜欢那个特定的线程池实现。我的意思是,你可以有多少个毫无意义的 pimpl 层?多少无意义的堆分配?而且,它默认通过引用传递,这在将东西传递给另一个线程时是一个可怕的想法。
我认为在这里争论是一个糟糕的计划。避免使用它们。
poolPtr->add([=]{ launchRange(77, func, i1, i2); });
这也消除了创建auto launchRange = []
lambda 的需要。错误最终变得更容易阅读。
推荐阅读
- python - Cloudwatch 发送到 SNS 的 JSON 有效负载中有什么?我怎样才能读取这些数据?
- python - 替换python列表中的特定模式索引项
- ssis - 无法启动程序 'DTS' OLE 已发送请求并正在等待回复?
- javascript - jQuery - 单击文件输入的父级并触发文件输入的单击事件后,它返回“递归过多”
- java - 如何在打开另一个 JFrame 时关闭一个 JFrame?
- jenkins - 我们如何通过使用与 Jenkins 中的代码相同的管道来传递(参数)三个节点从变量
- memory - 如何使用 gdb 或任何其他工具通过加载或存储操作(ARM 处理器)找到所有内存访问地址
- algorithm - BFS可以用来识别最远的顶点吗?
- scala - 由于某些字段的值未知,使用 Spark 写入 parquet 文件的数字格式异常
- laravel - 使用 Traefik、Nginx 和 Laravel 配置 Docker