Taskflow允许您通过将运行时对象作为任务的参数与调度运行时进行交互。这主要用于设计从Taskflow的现有设施扩展的专用并行算法。
创建Runtime对象
Taskflow允许静态任务和条件任务接受引用的tf::Runtime对象,该对象提供一组方法与调度运行时交互。以下示例创建一个静态任务,该任务利用tf::Runtime来显式调度在正常调度环境中永远不会运行的条件任务:
#include <taskflow/taskflow.hpp>
void print_str(char const* str) {
std::cout << str << std::endl;
}
int main() {
tf::Executor executor;
tf::Taskflow taskflow;
auto [A, C, D] = taskflow.emplace(
[](){ return 0; }, // 条件任务
[](){ print_str("C"); },
[](){ print_str("D"); }
);
auto B = taskflow.emplace(
[&C](tf::Runtime& rt){
print_str("B");
rt.schedule(C); // Runtime对象显式调用Task C
}
);
A.precede(B, C, D);
executor.run(taskflow).wait();
}
当条件任务A完成并返回0时,executor会移动到任务B。在正常情况下,任务C和D不会运行,因为它们的条件依赖性永远不会发生。这可以通过通过驻留在同一图中的任务的Runtime对象强制调度C或D来打破。在这里,任务B调用tf::Runtime::schedule来强制运行任务C,即使A和C之间的弱依赖性永远不会基于图结构本身发生。
同时,Runtime还可以用来复用一个Graph:
// create a custom graph
tf::Taskflow graph;
graph.emplace([](){ std::cout << "independent task 1\n"; });
graph.emplace([](){ std::cout << "independent task 2\n"; });
taskflow.emplace([&](tf::Runtime& rt){
// this worker coruns the graph through its work-stealing loop
rt.corun(graph);
});
executor.run_n(taskflow, 10000);