tokio多任务绑定cpu(绑核)

tokio 是 rust 生态中流行的异步运行时框架。在实际生产中我们如果希望 tokio 应用程序与特定的 cpu core 绑定该怎么处理呢?

首先我们先写一段简单的多任务程序。

use tokio;
use tokio::runtime;
use core_affinity;

fn tokio_sample() {
    let rt = runtime::Builder::new_multi_thread()
        .enable_all()
        .build()
        .unwrap();

    rt.block_on(async {
        for i in 0..4 {
            println!("num {}", i);
            tokio::spawn(async move {
                loop {
                    let mut sum: i32 = 0;
                    for i in 0..100000000 {
                        sum = sum.overflowing_add(i).0;
                    }
                    println!("sum {}", sum);
                }
            });
        }
    });
}

fn main() {
    tokio_sample();   
}

程序非常简单,首先构造一个 tokio runtime 环境,然后派生多个 tokio 并发,每个并发执行一个无限循环做 overflowing_add。overflowing_add 函数返回一个加法的元组以及一个表示是否会发生算术溢出的布尔值。如果会发生溢出,那么将返回包装好的值。然后取元祖的第一个元素打印。

这个程序运行在 Centos8,4 core cpu。通过 pidstat -t 1 -p $(pidof cpu_affinity_tokio) 的监控如下:

在这里插入图片描述

可以看到4个 core 负载几乎都是 100%。

要想把负载绑定在某一 core 上,需要使用 core_affinity_rs。core_affinity_rs 是一个用于管理 CPU 亲和力的 Rust crate。目前支持 Linux、Mac OSX 和 Windows。官方宣称支持多平台。

我们把代码修改一下:

fn tokio_affinity_cpu1() {
    let core_ids = core_affinity::get_core_ids().unwrap();
    println!("core num {}", core_ids.len());
    let core_id = core_ids[1];

    let rt = runtime::Builder::new_multi_thread()
        .on_thread_start(move || {
            core_affinity::set_for_current(core_id.clone());
        })
    .enable_all()
        .build()
        .unwrap();

    rt.block_on(async {
        for i in 0..4 {
            println!("num {}", i);
            tokio::spawn(async move {
                loop {
                    let mut sum: i32 = 0;
                    for i in 0..100000000 {
                        sum = sum.overflowing_add(i).0;
                    }
                    println!("sum {}", sum);
                }
            });
        }
    });
}

fn main() {  
   tokio_affinity_cpu1();
}

在构建多线程 runtime 时,在 on_thread_start 设置 cpu 亲和 cpu1。可以看到负载被绑定到了指定的 core 上,4 个线程各占 1/4 cpu。

在这里插入图片描述

上面的代码只是把负载绑定到了一个 core 上,那么要绑定多个核怎么办呢?
我们看看下面的代码

fn tokio_affinity_cpu1_cpu2() {
    let core_ids = core_affinity::get_core_ids().unwrap();
    println!("core num {}", core_ids.len());

    let rt = runtime::Builder::new_multi_thread()
        .enable_all()
        .build()
        .unwrap();

    let mut idx = 1;

    rt.block_on(async {
        for i in 0..4 {
            println!("num {}", i);
            let core_id = core_ids[idx];
            if idx.eq(&(core_ids.len() - 1)) {
                idx = 2;
            } else {
                idx += 1;
            }

            tokio::spawn(async move {
                let res = core_affinity::set_for_current(core_id);
                println!("{}", res);
                loop {
                    let mut sum: i32 = 0;
                    for i in 0..100000000 {
                        sum = sum.overflowing_add(i).0;
                    }
                    println!("sum {}", sum);
                }
            });
        }
    });
}


fn main() {
    tokio_affinity_cpu1_cpu2();
}

代码需要把所有负载绑在 core1 和 core2 上。原理是在派生任务中加入 core_affinity 设置。通过调整 idx,将派生并发平均绑定在指定的 core 上。代码运行的监控如下图。

在这里插入图片描述

参考:
文盘 Rust – tokio 绑定 cpu 实践
Rust入门秘籍-tokio简介
Rust语言圣经(Rust Course)-tokio
https://tokio.rs/tokio/tutorial

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

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

相关文章

【漏洞复现】云时空社会化商业ERP系统slogin SQL注入漏洞

漏洞描述: 云时空社会化商业ERP系统slogin存在SQL注入漏洞,攻击者可以通过此漏洞获取数据库敏感信息。 搜索语法: Fofa-Query: app"云时空社会化商业ERP系统" 漏洞详情: 1.云时空社会化商业ERP系统。 2.漏洞POC: …

GaussDB 数据导入导出工具介绍

本节课程一起来学习一下GaussDB数据库的导入导出。 目录 一、数据导入导出场景划分 1. gsql工具适用场景和使用方法 2. copy使用场景和使用方法 3.gs_dump工具使用方法 4. gs_restore工具使用方法 二、gs_loader介绍 1. 工具介绍 2.创建系统表和数据表 3.创建控制文…

mat转为txt的double数据||无截断误差保存多位小数

前情提要 需要将86400021的.mat数据存为visual studio可用的格式,主要是.csv数据或.txt数据 方法大概三种,一:csvwrite;二:save为txt;三:fprintf 一:csvwrite 1 csvwrite(ga_mat.…

Git merge的版本冲突实验

实验目的 发现 两个分支的 相同文件 怎样被修改 才会发生冲突? 实验过程 1.初始状态 现在目前有1.py、2.py两个文件,已经被git管理。现在我想制造冲突,看怎样的修改会发生冲突,先看怎么不会发生冲突。 目前仓库里的版本是这样…

简述大模型领域的CVP架构和RAG架构的区别

大模型领域的CVP(ChatGPT VectorDB Prompt)架构,是否等同于RAG增强式搜索。 首先,CVP是特指一个聊天系统相关的架构,即: ChatGPT:基于GPT模型的聊天机器人技术。 VectorDB:向量数…

【声呐仿真】学习记录0-服务器配置docker、ros环境

【声呐仿真】学习记录0-服务器配置docker、ros环境 前言一、~~0.设置mobaXterm~~1.拉取镜像2.服务器开启xhost,可视化(rviz、gazebo)3.创建容器,挂载数据卷4.测试宿主机与容器数据是否同步5.测试5.0测试xclock5.1测试ros小乌龟5.2…

bayesplot|分享一个可视化贝叶斯模型的R包

1.bayesplot介绍 该包主要用于贝叶斯模型的可视化分析,提供了一系列工具来帮助评估、理解和诊断贝叶斯模型。这个包特别适用于与 Stan 以及其他提供 MCMC 样本的软件如 JAGS 和 BUGS 的模型输出。 后验分布图:包括密度图、直方图和区间图,用于展示模型…

微信小程序和公众号打通,实现用户关注公众号送优惠券

前提 小程序 公众号 微信开放平台 小程序和公众号都需要绑定到同一个微信开放平台,因为要获取Unionid,unionid是什么 如果开发者拥有多个移动应用、网站应用、和公众账号(包括小程序),可通过 UnionID 来区分用户的唯一性&#xf…

【Linux】驱动_2_字符驱动

1. Linux设备分类 字符设备: 指应用程序按字节/字符来读写数据的设备。通常为传真、虚拟终端和串口调制解调器、键盘之类设备提供流通信服务,通常不支持随机存取数据。字符设备在实现时大多不使用缓存器。系统直接从设备读/写每一个字符。块设备: 通常支持随机存取…

Jenkins 打包报错记录 error: index-pack died of signal 15

问题背景,打包每次到92%时就会报错,试了好几次都是同样的错误 14:56:53 fatal: index-pack failed 14:56:53 14:56:53 at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommandIn(CliGitAPIImpl.java:2734) 14:56:53 at org.jenkinsci.plugi…

GoLand远程开发IDE:使用SSH远程连接服务器进行云端编程

目录 ⛳️推荐 1. 安装配置GoLand 2. 服务器开启SSH服务 3. GoLand本地服务器远程连接测试 4. 安装cpolar内网穿透远程访问服务器端 4.1 服务器端安装cpolar 4.2 创建远程连接公网地址 5. 使用固定TCP地址远程开发 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站&am…

【复现】金和OA-jc6 RCE漏洞_74

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一: 四.修复建议: 五. 搜索语法: 六.免责声明 一.概述 金和C6协同管理平台包括协同办公管理,人力资源管理,项目管理,客户关系管理,企业目标管理,费用管理,移动办公,微信办公等多个业务范…

Java——内存溢出如何排查

1、模拟内存移除场景 public class OOMTest {public static void main(String[] args) {List<byte[]> memoryLeakArray new ArrayList<>();for (int i 0; i<1024; i){byte[] bytes new byte[1024 * 1024];memoryLeakArray.add(bytes);}} }初始化启动参数最大…

小心!那个走了的员工可能带走了公司的秘密

数据泄露是企业安全的一大隐患&#xff0c;尤其是离职员工带走公司数据的问题&#xff0c;这是一种常被忽视的内部威胁。离职员工可能因为种种原因&#xff0c;带走了他们曾经可以访问的公司数据。而这些数据如果落入了不当的地方&#xff0c;可能会给企业带来严重的损害。那么…

力扣数据库题库学习(4.24日)

1068. 产品销售分析 I 问题链接 思路分析 编写解决方案&#xff0c;以获取 Sales 表中所有 sale_id 对应的 product_name 以及该产品的所有 year 和 price 。返回结果表 无顺序要求 。 这个问题很简单&#xff0c;查询两张表内的指定字段。这个考的其实就是数据库的连接&am…

23种设计模式(Java版,超详细!)

文章目录 一、什么是设计模式二、设计模式的分类三、设计模式的基本要素四、23种设计模式概览五、设计模式间的关系六、设计模式详解6.1. 工厂方法模式&#xff08;Factory Method&#xff09;6.2. 抽象工厂模式&#xff08;Abstract Factory&#xff09;6.3. 建造者模式&#…

屏幕状态自动检测+鼠标自动操作

目录 一、写在前面 1.1适用场景 1.2涉及到的库 二、函数库 2.1pyautogui-屏幕截图&鼠标操作 2.1.1屏幕截图screenshot函数 2.1.2鼠标移动及单击 2.2Opencv-模板匹配 2.2.1matchTemplate函数 2.2.2minMaxLoc函数 2.2.3相关代码 2.3base64-图片转base64 2.3.1在线…

【行为型模式】模板方法模式

一、模板方法模式概述 模板方法模式定义&#xff1a;在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。(类对象型模式) 模板方法中的基本方法是实现算法的各个步骤&#xff0c;是模板方法的…

谷歌搜索SEO优化需要做什么?

最基本的要求&#xff0c;网站基础要优化好&#xff0c;让你的网站更加友好地服务于用户和搜索引擎&#xff0c;首先你要保证你的网站也适配手机端&#xff0c;现在手机端&#xff0c;如果你的网站在手机上打开慢&#xff0c;或者没有适配手机端&#xff0c;让用户用手机看着电…

Echarts X轴类目名太长时隐藏显示全部

echarts图表X轴 在柱状图中,X轴类目名如果数据太长; echarts会默认进行隐藏部分字段; 如果我们想让每一个类目名都显示出来,需要进行额外的处理X轴类目名太长时,默认只显示一部分类目名 <!DOCTYPE html> <html lang="en"> <head><meta ch…