0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

jf_wN0SrCdH 来源:Rust语言中文社区 2023-04-09 10:24 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

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

我们看看下面的例子

fn main(){


        let max_task = 1;


        let rt = runtime::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::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::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
符合预期,代码不多,有兴趣的同学可以动手尝试一下。

审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 线程池
    +关注

    关注

    0

    文章

    57

    浏览量

    7315
  • 非阻塞
    +关注

    关注

    0

    文章

    13

    浏览量

    2346
  • Rust
    +关注

    关注

    1

    文章

    240

    浏览量

    7477
  • Tokio
    +关注

    关注

    0

    文章

    12

    浏览量

    232

原文标题:文盘Rust -- 用Tokio实现简易任务池

文章出处:【微信号:Rust语言中文社区,微信公众号:Rust语言中文社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    SQLx在Rust语言中的基础用法和进阶用法

    SQLx是一个Rust语言的异步SQL执行库,它支持多种数据库,包括MySQL、PostgreSQL、SQLite等。本教程将以MySQL数据库为例,介绍SQLx在Rust语言中的基础用法和进阶用法
    的头像 发表于 09-19 14:32 6972次阅读

    什么是Tokio模块 Channel?

    Rust 语言是一种系统级编程语言,它具有强类型和内存安全性。Rust 语言中的 Tokio 模块是一个异步编程库,它提供了一种高效的方式来处理异步任务。其中,channel 是
    的头像 发表于 09-19 15:57 1687次阅读

    使用tokio实现一个简单的Client和Server通讯模型

    本系列是关于Rust构建一个KV Server的系列文章,内容包括tokio做底层异步网络通讯、使用toml文件做配置、protobuf做传输协议、内存/RockDB做数据存储、事
    的头像 发表于 09-09 09:45 2946次阅读

    如何用Rust构建一个KV Server系列

    本系列是关于Rust构建一个KV Server的系列文章,内容包括tokio做底层异步网络通讯、使用toml文件做配置、protobuf做传输协议、内存/RockDB做数据存储、事
    的头像 发表于 09-14 10:03 1764次阅读

    WasmEdge增加了Tokio支持

    WasmEdge 成功地移植了 tokio(一个 Rust 异步运行时)到 Wasm:https://github.com/WasmEdge/tokio。其秘
    的头像 发表于 12-05 11:55 1319次阅读

    Rust--r2d2实现redis连接

    我们在开发应用后端系统的时候经常要和各种数据库、缓存等资源打交道。这一期,我们聊聊如何访问redis 并将资源化。
    的头像 发表于 12-12 10:32 1400次阅读

    Rust -- rust连接oss

    我们以 [S3 sdk](https://github.com/awslabs/aws-sdk-rust)为例来说说基本的连接与操作,作者验证过aws、京东云、阿里云。主要的增删改查功能没有什么差别。
    的头像 发表于 05-12 16:18 1104次阅读

    Rust -- tokio绑定cpu实践

    )。core_affinity_rs是一个用于管理CPU亲和力的Rust crate。目前支持Linux、Mac OSX和Windows。官方宣称支持多平台,本人只做了linux 操作系统的测试。
    的头像 发表于 06-11 15:32 994次阅读
    <b class='flag-5'>文</b><b class='flag-5'>盘</b><b class='flag-5'>Rust</b> -- <b class='flag-5'>tokio</b>绑定cpu实践

    Tokio 模块的优雅停机机制

    的讲解。 Tokio 模块简介 TokioRust 语言中的异步编程框架,它提供了一些基础的异步编程工具,如异步 IO、任务调度等。Tokio
    的头像 发表于 09-19 15:26 1277次阅读

    如何使用Tokio 和 Tracing模块构建异步的网络应用程序

    Rust 语言中,Tokio 是一个非常流行的异步运行时,它提供了高效的异步 I/O 操作和任务调度。而 Tracing 则是一个用于应用程序跟踪的框架,它可以帮助我们理解应用程序的行为和性能
    的头像 发表于 09-19 15:29 1398次阅读

    如何使用 Tokio 模块的Channel

    Channel 是一种在多线程环境下进行通信的机制,可以让线程之间互相发送消息和共享数据。Rust 语言中的 Tokio 模块提供了一种异步的 Channel 实现,使得我们可以在异步程序中方
    的头像 发表于 09-19 15:38 1513次阅读

    tokio模块channel中的使用场景和优缺点

    以让不同的线程之间通过发送和接收消息来传递数据,从而实现线程之间的协作和同步。 在 Rust 语言中,tokio 模块的 channel 组件提供了
    的头像 发表于 09-19 15:54 1702次阅读

    Tokio 的基本用法

    Tokio 是一个异步 I/O 框架,它提供了一种高效的方式来编写异步代码。它使用 Rust 语言的 Futures 库来管理异步任务,并使用 Reactor 模式来处理 I/O 事件。 本系
    的头像 发表于 09-19 16:05 1570次阅读

    Channel模块的使用方法示例

    Rust 语言中的 Tokio 模块是一个异步编程库,它提供了一种高效的方式来处理异步任务。其中,channel 是 Tokio 模块中的一个重要组成部分,它可以用于在异步
    的头像 发表于 09-20 11:47 2033次阅读

    高并发内存项目实现

    本项目实现了一个高并发内存,参考了Google的开源项目tcmalloc实现简易版;其功能就是实现高效的多线程内存管理。由功能可知,高并
    的头像 发表于 11-09 11:16 1306次阅读
    高并发内存<b class='flag-5'>池</b>项目<b class='flag-5'>实现</b>