关于go task
提供了另一种更简单的使用计算任务的方法,模仿go语言实现的go task。
使用go task来实计算任务无需定义输入与输出,所有数据通过函数参数传递。
与ThreadTask 区别
ThreadTask 是有模板,IN 和 OUT, ThreadTask 依赖 输入输出。
而 GoTask 不依赖,而是直接将函数打包成 go 这个callback,等待线程池消费。
1.示例程序
我们想异步的运行一个加法函数:void add(int a, int b, int& res);
并且我们还想在函数运行结束的时候打印出结果。于是可以这样实现:
#include <stdio.h>
#include <utility>
#include "workflow/WFTaskFactory.h"
#include "workflow/WFFacilities.h"
void add(int a, int b, int& res)
{
res = a + b;
}
int main(void)
{
WFFacilities::WaitGroup wait_group(1);
int a = 1;
int b = 1;
int res;
WFGoTask *task = WFTaskFactory::create_go_task("test", add, a, b, std::ref(res));
task->set_callback([&](WFGoTask *task) {
printf("%d + %d = %d\n", a, b, res);
wait_group.done();
});
task->start();
wait_group.wait();
return 0;
}
2. 继承顺序
3.源码分析
template<class FUNC, class... ARGS>
inline WFGoTask *WFTaskFactory::create_go_task(const std::string& queue_name,
FUNC&& func, ARGS&&... args)
{
auto&& tmp = std::bind(std::forward<FUNC>(func),
std::forward<ARGS>(args)...);
return new __WFGoTask(WFGlobal::get_exec_queue(queue_name),
WFGlobal::get_compute_executor(),
std::move(tmp));
}
class __WFGoTask : public WFGoTask
{
protected:
virtual void execute()
{
this->go();
}
protected:
std::function<void ()> go;
public:
__WFGoTask(ExecQueue *queue, Executor *executor,
std::function<void ()>&& func) :
WFGoTask(queue, executor),
go(std::move(func))
{
}
};
其他和ThreadTask一致,还是通过线程池去执行execute(),从而进行用户函数的执行
4.参考链接
https://github.com/chanchann/workflow_annotation/blob/main/src_analysis/12_go_task.md
https://github.com/sogou/workflow/blob/master/docs/about-go-task.md