A Task in Taskflow is a callable object for which the operation std::invoke is applicable. It can be either a functor, a lambda expression, a bind expression, or a class object with operator() overloaded. All tasks are created from tf::Taskflow, the class that manages a task dependency graph.
tf::Taskflow
可以理解成计算图,用于管理计算节点,添加节点的方法:
placeholder返回一个task对象的handleemplace参数可以是多个callable对象,返回对应的task handle
示例:
tf::Taskflow taskflow;
tf::Task A = taskflow.placeholder();
tf::Task B = taskflow.emplace([] () { std::cout << "task B\n"; });
auto [D, E, F] = taskflow.emplace(
[](){ std::cout << "Task A\n"; },
[](){ std::cout << "Task B\n"; },
[](){ std::cout << "Task C\n"; }
);tf::Task
可以理解成计算图的计算节点,管理计算任务。常用方法:
name(const std::string &name)赋予名字给任务name()获取任务名字work(CallableObj&& callable)赋予新“工作”给节点template <typename... Ts> Task& precede(Ts&&... tasks)指定前继节点template <typename... Ts> Task& Task::succeed(Ts&&... tasks)指定后继节点template <typename T> Task& Task::composed_of(T& object)添加子图
在每个task,都是使用通用的多态函数包装器— std::function 来存储和调用每个 _callable,_因此函数callable需要满足function的要求:
-
可复制
#include <iostream> #include <functional> #include <memory> int main() { // 创建一个 std::function 对象 std::function<void()> task = [ptr = std::make_unique<int>(1)]() { std::cout << "captured unique pointer is not copyable"; }; // 调用 task task(); // 尝试复制 task std::function<void()> task_copy = task; // 编译失败 return 0; } // compile error: /usr/include/c++/11/bits/std_function.h: In instantiation of ‘std::function<_Res(_ArgTypes ...)>::function(_Functor&&) [with _Functor = main()::<lambda()>; _Constraints = void; _Res = void; _ArgTypes = {}]’: main.cpp:17:5: required from here /usr/include/c++/11/bits/std_function.h:439:69: error: static assertion failed: std::function target must be copy-constructible 439 | static_assert(is_copy_constructible<__decay_t<_Functor>>::value, // 过不了可复制这一静态断言 -
…
tf::Executor
特点:
- 可以前后用于多次执行相同/不同的taskflow
- 线程安全
run_*方法是非阻塞返回- 使用
work-stealing算法来调度任务执行
Important
Attention
A running taskflow must remain alive during its execution. It is your responsibility to ensure a taskflow not being destructed when it is running.
Similarly, you should avoid touching a taskflow while it is running.