绑定 return 值和可变参数模板
bind return value and variadic templates
我正在尝试用 C++ 创建一个线程池。这个概念是 main 将创建一个新任务,ThreadPool class 将获取任务对象并执行其他工作。这是任务 class:
template<typename ... Arguments>
class Task{
//
public:
Task(std::function<void (Arguments...)> _func, Arguments... _args){
auto f1 = std::bind(_func, _args...);
f1();
};
void run(){
};
};
这就是我尝试使用它的方式:
#include <iostream>
#include <algorithm>
#include "Task.hpp"
void prtinhi(int a)
{
std::cout << a << std::endl;
return;
}
int main(){
Task<int> task(prtinhi, 5);
task.run();
return 0;
}
很明显,Task对象会传入ThreadPool,ThreadPool会根据某种逻辑调用运行()。
此代码 运行 成功打印 5。但我想要的是从 运行() 函数调用 f1()。如果我将任务 class 更改为将 auto f1
定义为 class 成员,我会收到错误消息:
non-static data member declared ‘auto’
如果我声明它是静态的,我就不能给它赋值。
那么我该如何解决呢?有更好的方法吗?
为什么任务需要知道函数参数?任务应该是一个 void()
类型擦除的可调用对象。
using Task = std::function<void()>;
Task task([]{ prtinhi(5); });
ThreadPool pool;
pool.schedule(task);
// ...
// `prtinhi(5)` will be eventually called.
如果需要获取return值,需要std::future
.
ThreadPool
可以实现如下:
struct ThreadPool
{
some_lockfree_queue<Task> _queue;
std::vector<std::thread> _workers;
void initialize()
{
for(int i = 0; i < num_threads; ++i)
{
_workers.emplace_back([this]
{
Task t = _queue.try_dequeue();
t();
});
}
}
};
std::bind
不好 (注意 this talk by STL for more info). You should use lambdas 绑定你需要的参数并返回一个空函数。
我正在尝试用 C++ 创建一个线程池。这个概念是 main 将创建一个新任务,ThreadPool class 将获取任务对象并执行其他工作。这是任务 class:
template<typename ... Arguments>
class Task{
//
public:
Task(std::function<void (Arguments...)> _func, Arguments... _args){
auto f1 = std::bind(_func, _args...);
f1();
};
void run(){
};
};
这就是我尝试使用它的方式:
#include <iostream>
#include <algorithm>
#include "Task.hpp"
void prtinhi(int a)
{
std::cout << a << std::endl;
return;
}
int main(){
Task<int> task(prtinhi, 5);
task.run();
return 0;
}
很明显,Task对象会传入ThreadPool,ThreadPool会根据某种逻辑调用运行()。
此代码 运行 成功打印 5。但我想要的是从 运行() 函数调用 f1()。如果我将任务 class 更改为将 auto f1
定义为 class 成员,我会收到错误消息:
non-static data member declared ‘auto’
如果我声明它是静态的,我就不能给它赋值。 那么我该如何解决呢?有更好的方法吗?
为什么任务需要知道函数参数?任务应该是一个 void()
类型擦除的可调用对象。
using Task = std::function<void()>;
Task task([]{ prtinhi(5); });
ThreadPool pool;
pool.schedule(task);
// ...
// `prtinhi(5)` will be eventually called.
如果需要获取return值,需要std::future
.
ThreadPool
可以实现如下:
struct ThreadPool
{
some_lockfree_queue<Task> _queue;
std::vector<std::thread> _workers;
void initialize()
{
for(int i = 0; i < num_threads; ++i)
{
_workers.emplace_back([this]
{
Task t = _queue.try_dequeue();
t();
});
}
}
};
std::bind
不好 (注意 this talk by STL for more info). You should use lambdas 绑定你需要的参数并返回一个空函数。