首页 > 其他分享 >文盘Rust -- 用Tokio实现简易任务池

文盘Rust -- 用Tokio实现简易任务池

时间:2023-04-14 16:48:04浏览次数:35  
标签:spawn set run thread -- max 文盘 任务 Tokio

作者:京东科技 贾世闻

Tokio 无疑是 Rust 世界中最优秀的异步Runtime实现。非阻塞的特性带来了优异的性能,但是在实际的开发中我们往往需要在某些情况下阻塞任务来实现某些功能。

我们看看下面的例子

fn main(){


        let max_task = 1;


        let rt = runtime::Builder::new_multi_thread()


            .worker_threads(max_task)


            


            .build()


            .unwrap();     


        rt.block_on(async {


            println!("tokio_multi_thread ");


            for i in 0..100 {


                println!("run {}", i);     


                tokio::spawn(async move {


                    println!("spawn {}", i);


                    thread::sleep(Duration::from_secs(2));


                });


            }


        });


    }

我们期待的运行结构是通过异步任务打印出99个 “spawn i",但实际输出的结果大概这样

tokio_multi_thread


run 0


run 1


run 2


.......


run 16


spawn 0


run 17


......


run 99


spawn 1


spawn 2


......


spawn 29


......


spawn 58


spawn 59

59执行完后面就没有输出了,如果把max_task设置为2,情况会好一点,但是也没有执行完所有的异步操作,也就是说在资源不足的情况下,Tokio会抛弃某些任务,这不符合我们的预期。那么能不能再达到了某一阀值的情况下阻塞一下,不再给Tokio新的任务呢。这有点类似线程池,当达达最大线程数的时候阻塞后面的任务待有释放的线程后再继续。

我们看看下面的代码。

fn main(){


        let max_task = 2;


        let rt = runtime::Builder::new_multi_thread()


            .worker_threads(max_task)


            .enable_time()


            .build()


            .unwrap();     


        let mut set = JoinSet::new();


        rt.block_on(async {


            for i in 0..100 {


                println!("run {}", i);


                while set.len() >= max_task {


                    set.join_next().await;


                }


                set.spawn(async move {


                    sleep().await;


                    println!("spawn {}", i);


                });


            }


            while set.len() > 0 {


                set.join_next().await;


            }


        });


    }

我们使用JoinSet来管理派生出来的任务。set.join_next().await; 保证至少一个任务被执行完成。结合set的len,我们可以在任务达到上限时阻塞任务派生。当循环结束,可能还有未完成的任务,所以只要set.len()大于0就等待任务结束。

输出大概长这样

running 1 test


tokio_multi_thread


run 0


run 1


spawn 0


run 2


spawn 1


......


run 31


spawn 30


run 32


spawn 31


run 33


......


run 96


spawn 95


run 97


spawn 96


run 98


spawn 97


run 99


spawn 98


spawn 99

符合预期,代码不多,有兴趣的同学可以动手尝试一下。

标签:spawn,set,run,thread,--,max,文盘,任务,Tokio
From: https://www.cnblogs.com/jingdongkeji/p/17317697.html

相关文章

  • fastjson 1.2.24 反序列化漏洞(审计分析)
    环境JDK8u181Fastjson1.2.24POC跟进parse方法跟进到底层deserialze方法Poc中传入的dataSourceName:ldap://192.168.3.229:8084/vnSYPYwMs值这里实际对应setDataSourceName方法,调用此方法并传入ldap跟进setDataSourceName方法,这里只是简单赋值 步出......
  • ArrayList类
    ArrayList类ArrayList简单介绍**感觉很像c++里面的vector**1.储存的类型都是相同的2.打印的时候直接打印内容而不是地址ArrayLsit的简单使用代码示例importjava.util.ArrayList;publicclassArray{publicstaticvoidmain(String[]args){ArrayLi......
  • Spring自定义参数解析器设计
    作者:京东零售 王鹏超1.什么是参数解析器@RequstBody、@RequstParam这些注解是不是很熟悉?我们在开发Controller接口时经常会用到此类参数注解,那这些注解的作用是什么?我们真的了解吗?简单来说,这些注解就是帮我们将前端传递的参数直接解析成直接可以在代码逻辑中使用的javaBean,......
  • 一文迅速掌握开发框架是什么
    在经济迅猛发展的今天,办公自动化已经成为潮流。应用快速开发框架可以为企业提质增效、做好数据管理、实现数字化发展。那么,开发框架是什么?带着这个问题,我们今天一起在本文中寻找答案吧。一、了解低代码技术平台服务商在产业分工新时代,紧跟市场发展潮流,与市场接轨,深入了解市场需......
  • docker -DockerFile
    1.dockerfile安装,编写我们的镜像来源:1.远程仓库拉取2.用仓库做成的镜像3.把备份的恢复4.使用dockerfile构建Dockerfile是由一系列命令和参数构成的脚本文件,这些命令应用于基础镜像并最终创建一个新的镜像。使用dockerfile不需要先创建容器在里面加东西,而是直接可以在镜像中......
  • nginx使用
    我使用的是windows环境1、下载nginx包文件https://nginx.org/en/download.html2、解压3、运行nginx.exe4、输入localhost:80启动成功 自己的项目在nginx中运行1、本地dist文件内容粘贴到nginx文件下的html目录中2、更改配置添加重定向,避免路由跳转404配置代理 ......
  • 创建包不分级,移动包失败
    新建包时不能分级,以及移动包时显示指定的目标包名称无效将此处取消勾选即可移动时显示指定的目标包名称无效可能是包命名出现问题,只能包含数字、字母、下划线、小圆点,但不能用数字开头,不能是关键字......
  • 二叉树先序,中序,后序遍历的非递归算法(一)
    前序遍历的非递归算法<法一>思路:二叉树的前序遍历过程:从树根开始沿着左子树一直深入,直到最左端无法深入时,返回;进入最近深入时遇到结点的右子树,再进行如此的深入和返回;直到最后从根节点的右子树返回到根节点为止;由其深入返回的过程我们知道可以用一个栈来帮助我们消除递归......
  • 批量给mycat配置文件增加数据库节点
    #!/bin/bash#修改mysqlschemamycat_schema_file=/opt/mycat/conf/schema.xmlcp$mycat_schema_file${mycat_schema_file}.bakdatabase_list='messagexuejie'#找到usercenter的行号,由于schema成对出现有可能换行,在其上一行增加schema更可靠last_schema_row_number=`sed......
  • 【Linux】添加用户并授权
    1.Centos添加用户并授权<!--添加用户-->useradd-d/home/zhangsan-mzhangsan<!--设置密码-->passwdzhangsan<!--授予sudo权限-->usermod-a-Gadmzhangsanusermod-a-Gsudozhangsan<!--或修改/etc/sudoers文件-->zhangsanALL=(ALL)AL......