Rust : tokio中select!

关于tokio的select宏,有不少的用途。包括超时和竞态选择等。

关于select宏需要关注,相关的异步条件,会同时执行,只是当有一个最早完成时,会执行"抛弃"和"对应"策略。

说明:对本文以下素材的来源表示感谢!

bash 复制代码
 https://zhuanlan.zhihu.com/p/14498925766

select宏分支匹配的定义:

bash 复制代码
<pattern> = <async expression> => <handler>

pattern当有返回值且需要处理,往往用val、Some(val)待形式表示,如果没有返回值或返回值不需处理,往往用"_"来表示。

而async expression部分,就是我们所指的condition_action部分。而handler部分就是分支对应的"后续任务"部分。

一、toml

bash 复制代码
[dependencies]
tokio = { version = "1.42.0",  features = ["full"] }

二、main.rs

说明:

condition_action为异步"条件任务";在后面的是"后续任务"。是否执行"后续任务"的前提是,哪个条件任务是最早完成。但这个选择是通过异步同时执行所有的"条件任务"PK出来的。

举个例子,可能更清楚:

比如学校某班级有3位同学,测试其运动水平高低,并决定水平最高的人可以参加学校运动会比赛(篮球或足球比赛,这个举例不一定合理)。假设设定测试条件任务是跑10000米(即condition_action),那么,我们可以让3位同学同时跑,首先冲过终点的人,马上去参加比赛("后续任务")。

当3位同学中,只要有人首先冲过终点(condition_action结束),就让他去代表参加比赛(执行后续任务,篮球或足球由其决定)。很显然,其它的人就不用跑了,可以停下来了,即被"抛弃"了,更不需要去参赛。

bash 复制代码
use tokio::time;

async fn conditon_action(s: String) -> String{
    println!("\t 执行条件任务 {} 开始.", s);
    time::sleep(time::Duration::from_secs(1)).await;
    println!("\t 执行条件任务 {} 结束! 后续执行 => {},其它任务不执行!", s,s);
    s
}

#[tokio::main]
async fn main() {
    for i in 0..3 {
        println!("Round {}:", i);
        time::sleep(time::Duration::from_secs(2)).await;
        // 注意:(1) select!会同时执行_A和_B两个任务;
        // (2)但是只会选择_A与_B中最先完成的任务对应的任务来执行后续的任务;
        // (3)同时,_A与_B中没有被执行完的部分,后续不执行。具体表现在condition_action函中有"开始"没有"结束".

        tokio::select! {
            val = conditon_action(i.to_string()+"_A") => {
                println!("\t 执行后续任务{} 开始.", val);
                time::sleep(time::Duration::from_secs(2)).await;
                println!("\t 执行后续任务{} 结束.", val);
            },
            val = conditon_action(i.to_string()+"_B") => {
                println!("\t 执行后续任务{} 开始.", val);
                time::sleep(time::Duration::from_secs(2)).await;
                println!("\t 执行后续任务{} 结束.", val);
            }
        }
    }
}

输出:

bash 复制代码
Round 0:
         执行条件任务 0_B 开始.
         执行条件任务 0_A 开始.
         执行条件任务 0_A 结束! 后续执行 => 0_A,其它任务不执行!
         执行后续任务0_A 开始.
         执行后续任务0_A 结束.
Round 1:
         执行条件任务 1_B 开始.
         执行条件任务 1_A 开始.
         执行条件任务 1_B 结束! 后续执行 => 1_B,其它任务不执行!
         执行后续任务1_B 开始.
         执行后续任务1_B 结束.
Round 2:
         执行条件任务 2_A 开始.
         执行条件任务 2_B 开始.
         执行条件任务 2_A 结束! 后续执行 => 2_A,其它任务不执行!
         执行后续任务2_A 开始.
         执行后续任务2_A 结束.

解读:

对于round0:

1、A和B条件任务均执行,但B任务提前完成,此时A任务未完成部分"抛弃"

2、执行后续B任务

对于round1:

1、A和B条件任务均执行,但A任务提前完成,此时B任务未完成部分"抛弃"

2、执行后续A任务.

对于round2:

1、A和B条件任务均执行,但A任务提前完成,此时B任务未完成部分"抛弃"

2、执行后续A任务.

从上面可以清晰看到,tokio的select!中"抛弃"和"后续执行"策略。

相关推荐
白仑色9 分钟前
Spring Boot + Thymeleaf + RESTful API 前后端整合完整示例
spring boot·后端·restful·thymeleaf·restfulapi
荷蒲44 分钟前
【小白量化智能体】应用5:编写通达信股票交易指标及生成QMT自动交易Python策略程序
开发语言·python
ljh5746491191 小时前
PHP password_verify() 函数
开发语言·php
lovix121 小时前
java进阶(三):单例、工厂、模版方法与代理模式详解
java·开发语言
小赖同学1 小时前
CAMEL 框架之 RolePlaying 角色扮演
人工智能·后端·aigc
无限大61 小时前
力扣每日一题--2025.7.15
后端
JohnYan1 小时前
Bun技术评估 - 16 Debug
javascript·后端·debug
天天摸鱼的java工程师1 小时前
百万数据导出Excel:从新手坑到老鸟方案
java·后端·面试
hqxstudying1 小时前
Java行为型模式---观察者模式
java·开发语言·windows·观察者模式