tokio多任务绑定cpu(绑核)

news2024/11/23 10:01:33

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

3.SpringCloud版本

1.SpringCloud与SpringBoot之间版本对应 2.服务拆分的注意事项 1.不同微服务,不要重复开发相同业务。 2.微服务的数据独立,每个微服务都有自己独立的数据库,不要访问其他微服务的数据库。 3.微服务可以将自己的的业务暴露为接口&#xff…

C++:基础语法

一、命名空间 在C/C中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化, 以避免命名冲突或名字污染,n…

24V转2.8V2A降压芯片WT6030

24V转2.8V2A降压芯片WT6030 WT6030是一种高效同步整流降压开关模式转换器,集成内部功率MOSFET。该器件在宽输入电源范围内提供3A峰值输出电流,展现出卓越的负载和线路调节性能。其设计仅需要最小数量的外部现成组件,并且采用了节省空间的ESO…

GITHUB的VB代码无法加载的问题解决

GITHUB里有不少好的VB代码,但是下载之后,经常出现工程加载出错的问题,例如: LOG文件为: 不能加载 0 行 0: 不能加载文件 D:\xxxx\Semi VB API Loader\frmMain.frm 。 原因其实很简单,github里的换行符是u…

如何在PostgreSQL中使用索引覆盖扫描提高查询性能?

文章目录 解决方案1. 创建合适的索引2. 确保查询能够使用索引覆盖扫描3. 调整查询以利用索引覆盖扫描4. 监控和调优 示例代码1. 创建索引2. 编写查询3. 检查是否使用索引覆盖扫描4. 调整索引 总结 在PostgreSQL中,索引是提高查询性能的关键工具之一。索引允许数据库…

C# 字面量null对于引用类型变量✓和值类型变量×

编译器让相同的字符串字面量共享堆中的同一内存位置以节约内存。 在C#中,字面量(literal)是指直接表示固定值的符号,比如数字、字符串或者布尔值。而关键字(keyword)则是由编程语言定义的具有特殊含义的标…

积极探索新质生产力,九河云携手华为云技术交流引领数智跃迁

4月18日,九河云携手华为云举办了华为云SA技术培训会议,培训邀请到华为云技术人员作为主讲人,通过理论讲解与案例结合的方式,围绕ECS和EBS之间的联动,调优和数据保护等方面展开,深入浅出地讲解了基于EBS部署…

Python从0到100(十四):高级函数及函数使用进阶

前言: 零基础学Python:Python从0到100最新最全教程。 想做这件事情很久了,这次我更新了自己所写过的所有博客,汇集成了Python从0到100,共一百节课,帮助大家一个月时间里从零基础到学习Python基础语法、Pyth…

【机器学习】分类与预测算法的评价与优化

以实际案例解析F1值与P-R曲线的应用 一、分类算法与性能评价的重要性二、F1值与P-R曲线的概念与意义三、实例解析:以垃圾邮件检测为例四、代码实现与结果分析五、结论与展望 在数据驱动的时代,机器学习算法以其强大的数据处理和分析能力,成为…

day07 51单片机-18B20温度检测

18B20温度检测 1.1 需求描述 本案例讲解如何从18B20传感器获取温度信息并显示在LCD上。 1.2 硬件设计 1.2.1 硬件原理图 1.2.3 18B20工作原理 可以看到18B20有两根引脚负责供电,一根引脚负责数据交换。18B20就是通过数据线和单片机进行数据交换的。 1&#xf…

PROSAIL模型前向模拟与植被参数遥感提取代码实现

原文链接:PROSAIL模型前向模拟与植被参数遥感提取代码实现https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247602140&idx7&sn7c4ca9239865d536ba81ba4c26a34031&chksmfa820e3bcdf5872d540c0dfe8c533c8696c8b4658427aab254f246a739f96b36bc37…

GPT 在目标设定中的应用:实现梦想的技术方法

在技术快速进步的时代,我们设定和实现目标的方式正在不断发展。 该领域最重要的创新之一是引入生成式预训练 Transformer (GPT)。 本文将探讨 GPT 技术如何彻底改变目标设定的艺术,提供实用的见解和案例研究来展示其影响。 GPT 和目标设定简介 ​ 了解 …

Ansible安装基本原理及操作(初识)

作者主页:点击! Ansible专栏:点击! 创作时间:2024年4月23日15点18分 Ansible 是一款功能强大且易于使用的IT自动化工具,可用于配置管理、应用程序部署和云端管理。它使用无代理模式(agentles…

控制台居然可以这么玩?五分钟带你上手ANSI指令,实现一个log工具包

目录 前言 基础知识 进阶实践 ANSI参数 ANSI类 JSLog类 工具的使用说明 配置相关 全局配置项 默认配置 基本用法 打印字符 添加全局配置项 清空所有样式及操作行为 校验传入的参数是否正确 样式控制 Node环境 浏览器中 光标控制指令 光标位置偏移 滚动条控…

Pytorch:张量的梯度计算

目录 一、自动微分简单介绍1、基本原理2、梯度计算过程3、示例:基于 PyTorch 的自动微分a.示例详解b.梯度计算过程c.可视化计算图 4、总结 二、为什么要计算损失,为何权重更新是对的?1、梯度下降数学原理2、梯度上升 三、在模型中使用自动微分…

力扣HOT100 - 199. 二叉树的右视图

解题思路&#xff1a; 相当于层序遍历&#xff0c;然后取每一层的最后一个节点。 class Solution {public List<Integer> rightSideView(TreeNode root) {if (root null) return new ArrayList<Integer>();Queue<TreeNode> queue new LinkedList<>…

element中file-upload组件的提示‘按delete键可删除’,怎么去掉?

问题描述 element中file-upload组件会出现这种提示‘按delete键可删除’ 解决方案&#xff1a; 这是因为使用file-upload组件时自带的提示会盖住上传的文件名&#xff0c;修改一下自带的样式即可 ::v-deep .el-upload-list__item.is-success.focusing .el-icon-close-tip {d…

vue 关键字变红

1.html <div v-html"replaceKeywordColor(item.title)" ></div> 2.js //value为搜索框内绑定的值 replaceKeywordColor(val) {if (val?.includes(this.value) && this.value ! ) {return val.replace(this.value,<font color"red&…

PyCharm 中的特殊标记

再使用 PyCharm 开发 Python 项目的时候&#xff0c;经常会有一些特殊的标记&#xff0c;有些是编辑器提示的代码规范&#xff0c;有些则为了方便查找而自定义的标记。 我在之前写过一些关于异常捕获的文章&#xff1a;Python3 PyCharm 捕获异常报 Too broad exception clause…

【电控笔记5.8】数字滤波器设计流程频域特性

数字滤波器设计流程&频域特性 2HZ : w=2pi2=12.56 wc=2*pi*5; Ts=0.001; tf_lpf =