Taskflow 简单使用

Hello World

#include <taskflow/taskflow.hpp>

int main() {
    tf::Executor executor; 
    tf::Taskflow taskflow;
    // 返回一个std::tuple<tf::Task, tf::Task, tf::Task, tf::Task> 
    auto [A, B, C, D] = taskflow.emplace(
        [](){std::cout<<"A"<<std::endl;},
        [](){std::cout<<"B"<<std::endl;},
        [](){std::cout<<"C"<<std::endl;},
        [](){std::cout<<"D"<<std::endl;}
    );

    A.precede(B, C);
    D.succeed(B, C);
    executor.run(taskflow).wait();
    

    return 0;
}

内置一个性能profiler,使用方式:

TF_ENABLE_PROFILER=simple.json ./simple # 可执行文件
cat simple.json 

然后把内容复制到TFProf。

创建一个Subflow Graph

流程如下:
在这里插入图片描述

#include <taskflow/taskflow.hpp>

void put(const std::string& str) {
    std::cout<<str<<std::endl;
}

int main() {
    tf::Executor executor; 
    tf::Taskflow taskflow;
    // 构建三个空任务,并命名
    tf::Task A = taskflow.emplace([](){put("A");}).name("A");
    tf::Task C = taskflow.emplace([](){put("C");}).name("C");
    tf::Task D = taskflow.emplace([](){put("D");}).name("D");

    // 构建一个子流,并命名
    tf::Task B = taskflow.emplace([](tf::Subflow& subflow){
        auto [B1, B2, B3] = subflow.emplace(
            [](){put("B1");},
            [](){put("B2");},
            [](){put("B3");} 
        );
        B3.succeed(B1, B2);
    }).name("B");

    A.precede(B, C);
    D.succeed(B, C);
    executor.run(taskflow).wait();
    

    return 0;
}

控制流

循环执行条件,直到返回true,才执行下一步:
在这里插入图片描述

#include <taskflow/taskflow.hpp>

void put(const std::string& str) {
    std::cout<<str<<std::endl;
}

int main() {
    tf::Executor executor; 
    tf::Taskflow taskflow;
    // 构建三个空任务,并命名
    tf::Task init = taskflow.emplace([](){put("init");}).name("init");
    tf::Task stop = taskflow.emplace([](){put("stop");}).name("stop");
    tf::Task cond = taskflow.emplace(
        [](){
            int p = std::rand() % 2;
            put(std::to_string(p).c_str());
            return p;
        }
    ).name("cond");

    init.precede(cond);
    cond.precede(cond,stop); // cond 需要返回True后才解除对cond的依赖
    executor.run(taskflow).wait();
    return 0;
}

任务组

一个taskflow的流程中,还可以嵌入另一个taskflow。
在这里插入图片描述

#include "taskflow/core/taskflow.hpp"
#include <taskflow/taskflow.hpp>

void put(const std::string& str) {
    std::cout<<str<<std::endl;
}


int main() {
    tf::Executor executor; 
    tf::Taskflow f1, f2;
    
    tf::Task f1a = f1.emplace([](){put("f1a");}).name("f1a");
    tf::Task f1b = f1.emplace([](){put("f1b");}).name("f1b");
    tf::Task f1_task_module = f2.composed_of(f1).name("f1_task_module"); // 表示f1是f2的一个task

    tf::Task f2a = f2.emplace([](){put("f2a");}).name("f2a");
    tf::Task f2b = f2.emplace([](){put("f2b");}).name("f2b");
    tf::Task f2c = f2.emplace([](){put("f2c");}).name("f2c");

    f1_task_module.succeed(f2a, f2b).precede(f2c); // 在f2c之前,在f2a, f2b之后
    
    executor.run(f2).wait();
  
    return 0;
}

异步任务

taskflow 支持开启异步任务,动态探索并行度:

#include "taskflow/core/async_task.hpp"
#include "taskflow/core/task.hpp"
#include "taskflow/core/taskflow.hpp"
#include <future>
#include <taskflow/taskflow.hpp>

// 线程不安全,可能会出现打印异常
void put(const std::string& str) {
    std::cout<<str<<std::endl;
}


int main() {
    tf::Executor executor; 
    tf::Taskflow taskflow;
    
    // 第一种方式,通过async的方式注册,并将解决使用future传递
    std::future<int> future = executor.async([](){
        put("async task returns 1");
        return 1;
    }); 

    // 第二种方式,丢弃返回值的异步
    executor.silent_async([](){
        put("async task does not return");
    });

    // 第三种方式,创建异步,并进行动态依赖
    tf::AsyncTask A = executor.silent_dependent_async([](){put("A");});
    tf::AsyncTask B = executor.silent_dependent_async([](){put("B");}, A); // B依赖A
    tf::AsyncTask C = executor.silent_dependent_async([](){put("C");}, A); // C依赖A
    tf::AsyncTask D = executor.silent_dependent_async([](){put("D");}, B, C); // D依赖B和C

    executor.wait_for_all(); // 等待所有异步任务结束
    return 0;
}

执行一个 Taskflow

executor提供了几种线程安全的方法来运行任务流。

// runs the taskflow once
tf::Future<void> run_once = executor.run(taskflow); 

// wait on this run to finish
run_once.get();

// run the taskflow four times
executor.run_n(taskflow, 4);

// runs the taskflow five times
executor.run_until(taskflow, [counter=5](){ return --counter == 0; });

// block the executor until all submitted taskflows complete
executor.wait_for_all();

可视化图结构

使用dump,生成定义好的结构图,生成的内容复制到下面的网站:
GraphViz Online

#include <taskflow/taskflow.hpp>
int main() {
    tf::Taskflow taskflow;

    tf::Task A = taskflow.emplace([] () {}).name("A");
    tf::Task B = taskflow.emplace([] () {}).name("B");
    tf::Task C = taskflow.emplace([] () {}).name("C");
    tf::Task D = taskflow.emplace([] () {}).name("D");
    tf::Task E = taskflow.emplace([] () {}).name("E");
    A.precede(B, C, E);
    C.precede(D);
    B.precede(D, E);

    // dump the graph to a DOT file through std::cout
    taskflow.dump(std::cout); 

    return 0;
}
digraph Taskflow {
subgraph cluster_p0xffffd542ef38 {
label="Taskflow: p0xffffd542eee0";
p0xffffa6914830[label="A" ];
p0xffffa6914830 -> p0xffffa6914928;
p0xffffa6914830 -> p0xffffa6914a20;
p0xffffa6914830 -> p0xffffa6914c10;
p0xffffa6914928[label="B" ];
p0xffffa6914928 -> p0xffffa6914b18;
p0xffffa6914928 -> p0xffffa6914c10;
p0xffffa6914a20[label="C" ];
p0xffffa6914a20 -> p0xffffa6914b18;
p0xffffa6914b18[label="D" ];
p0xffffa6914c10[label="E" ];
}
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/499798.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

金三银四面试题(六):对象大小知多少

对象和数组在JVM如何在堆中布局&#xff1f;更常见地问法就是对象头都包含哪些信息 在JVM中对象和数组尽管都是连续的内存块。但在堆内存中的布局方式有些不同。 对象的组成 对象在JVM中可以分为三个部分&#xff0c;对象头&#xff08;Header&#xff09;&#xff0c;实例数…

SoC芯片的DVFS技术详解

​A72训练营很多同学问DVFS技术怎么实现的&#xff0c;这里小编就和大家掰扯掰扯SoC芯片的DVFS技术吧。 1. DVFS技术介绍 DVFS&#xff08;Dynamic Voltage and Frequency Scaling&#xff09;即动态电压频率调节技术&#xff0c;是一种高效的低功耗技术&#xff0c;它通过动态…

初始化脚手架

说明: 1 --- Vue脚手架是Vue官方提供的标准化开发工具&#xff08;开发平台&#xff09; 2 --- 最新的版本是 4.x 3 --- 文档 Vue CLI 具体步骤: 1 --- 如果下载缓慢请配置npm淘宝镜像npm config set registry http://registry.npm.taobao.org 2 --- 全局安装 vue/cli npm ins…

Apache Kafka + 矢量数据库 + LLM = 实时 GenAI

公众号&#xff1a;Halo咯咯 生成式人工智能 (GenAI) 支持先进的人工智能用例和创新&#xff0c;但也改变了企业架构的外观。大型语言模型 (LLM)、向量数据库和检索增强生成 (RAG) 需要新的数据集成模式和数据工程最佳实践。 Apache Kafka 和 Apache Flink 的数据流在大规模实时…

CIM搭建实现发送消息的效果

目录 背景过程1、下载代码2、进行配置3、直接启动项目4、打开管理界面5、启动web客户端实例项目6、发送消息 项目使用总结 背景 公司项目有许多需要发送即时消息的场景&#xff0c;之前一直采用的是传统的websocket连接&#xff0c;它会存在掉线严重&#xff0c;不可重连&…

推荐算法策略需求-rank model优化

1.pred_oobe (base) [rusxx]$ pwd /home/disk2/data/xx/icode/baidu/oxygen/rus-pipeline/pipeline-migrate/UserBaseActiveStatPipeline/his_session (base) [rusxx]$ sh test.sh 2. user_skill_history_dict_expt2包含userid [workxx]$ vim /home/work/xx/du-rus/du_rus_o…

2.2.1.3-移动平均线

跳转到根目录&#xff1a;知行合一&#xff1a;投资篇 已完成&#xff1a; 1、投资&技术   1.1.1 投资-编程基础-numpy   1.1.2 投资-编程基础-pandas   1.2 金融数据处理   1.3 金融数据可视化 2、投资方法论   2.1.1 预期年化收益率   2.1.2 一个关于yaxb的…

Docker命令及部署Java项目

文章目录 简介Docker镜像镜像列表查找镜像拉取镜像删除镜像镜像标签 Docker容器容器启动容器查看容器停止和重启后台模式和进入强制停止容器清理停止的容器容器错误日志容器别名及操作 Docker部署Java项目 简介 Docker是一种容器化技术&#xff0c;可以帮助开发者轻松打包应用…

python练习五

1. 给定一个包含n1个整数的数组nums&#xff0c;其数字在1到n之间&#xff08;包含1和n&#xff09;&#xff0c;可知至少存在一个重复的整数&#xff0c;假设只有一个重复的整数&#xff0c;请找出这个重复的数 def find_difnumber(ls):for index in range(0, len(ls)):for n…

如何使用命令行对RK开发板进行OpenHarmony版本烧录?

问题 在 OpenHarmony 自动化测试环境中&#xff0c;需要对流水线上的 RK 设备进行烧录&#xff0c;图形工具只能人工操作&#xff0c;那么有什么方法可以纯命令行进行自动化烧录呢&#xff1f; 思路 我们发现 RK 开发板实际是使用 upgrade_tool 的执行文件进行烧录的&#x…

力扣Lc24--- 434. 字符串中的单词数(java版)-2024年3月29日

1.题目描述 2.知识点 注1&#xff1a; \\s: 匹配一个或多个空格字符。|: 表示逻辑或&#xff0c;用于分隔不同的正则表达式部分。(?[\\p{Punct}]): 正向前瞻&#xff0c;匹配任何标点符号之前的位置。(?<[\\p{Punct}]): 正向后顾&#xff0c;匹配任何标点符号之后的位置…

工厂能耗管控物联网解决方案

工厂能耗管控物联网解决方案 工厂能耗管控物联网解决方案是一种创新的、基于先进技术手段的能源管理系统&#xff0c;它深度融合了物联网&#xff08;IoT&#xff09;、云计算、大数据分析以及人工智能等前沿科技&#xff0c;以实现对工业生产过程中能源消耗的实时监测、精确计…

github项目名称变更sourcetree如何同步

github项目名称变更sourcetree如何同步 方法1:删除本地仓库 重新从URL克隆 方法2:修改远程地址链接 1.打开项目所在文件夹的终端 2.删除本地关联的这个远程仓库origin git remote rm origin 3.关联修改名字后的远程仓库地址 git remote add origin <新的远程仓库地址&…

前端超分辨率技术应用:图像质量提升与场景实践探索-设计篇

超分辨率&#xff01; 引言 在数字化时代&#xff0c;图像质量对于用户体验的重要性不言而喻。随着显示技术的飞速发展&#xff0c;尤其是移动终端视网膜屏幕的广泛应用&#xff0c;用户对高分辨率、高质量图像的需求日益增长。然而&#xff0c;受限于网络流量、存储空间和图像…

代码随想录算法训练营第35天| 435. 无重叠区间、763.划分字母区间、56. 合并区间

435. 无重叠区间 题目链接&#xff1a;无重叠区间 题目描述&#xff1a;给定一个区间的集合 intervals &#xff0c;其中 intervals[i] [starti, endi] 。返回 需要移除区间的最小数量&#xff0c;使剩余区间互不重叠 。 解题思想&#xff1a; 这道题目和射气球很像。 *“需…

深入浅出MySQL主从复制与读写分离原理及其实践

目录 一、主从复制 &#xff08;一&#xff09;主从复制简介 1.基本概述 2.复制类型 &#xff08;二&#xff09;主从复制流程与影响因素 1.主从复制的流程 2.影响因素 &#xff08;三&#xff09;实现主从复制 1.搭建时间同步 2.配置master服务器 2.1 开启二进制日…

C++11入门手册第一节,学完直接上手Qt(共两节)

入门 hello.cpp #include <iostream>int main() { std::cout << "Hello Quick Reference\n"<<endl; return 0;} 编译运行 $ g hello.cpp -o hello$ ./hello​Hello Quick Reference 变量 int number 5; // 整数float f 0.95; //…

分享vue3+OpenTiny UI+cesium.js实现三维地球

效果图 使用vue3 OpenTiny UI cesium 实现三维地球 node.js > v16.0 opentiny vue3 ui安装指南 https://opentiny.design/tiny-vue/zh-CN/os-theme/docs/installation yarn add opentiny/vue3 项目依赖 "dependencies": {"opentiny/vue": "3…

每日一练 两数相加问题(leetcode)

原题如下&#xff1a; 这道题目是一道链表题&#xff0c;我们对于这种链表类&#xff0c;很显然我们最后输出的是初始节点&#xff0c;所以我们要保留我们的初始头指针&#xff0c;那么我们的第一步一定是把头指针保留一份&#xff0c;然后再让头指针往后进行操作。那么我们进行…

EXCEL VBA根据表数据写入数据库中

EXCEL VBA根据表数据写入数据库中 Option Explicithttps://club.excelhome.net/thread-1687531-1-1.htmlSub UpdateAccess()Const adStateOpen 1Dim vData, i As Variant, j As LongDim AccessTable As String, ExcelTable As String, ExcelFile As String, AccessFile As Str…