Rust tokio::task::LocalSet 运行模式

首先 tokio 是 一个 rust 的异步运行时。

LoacSet 可以理解为,一个固定在线程内部的任务队列。

但是里面的运行模式,我也看不懂源码。于是就写个例子测试一下。

use chrono::Local;
use tokio::{self, runtime::Runtime, time};

fn now() -> String {
    Local::now().format("%Y年%m月%d日 %H:%M:%S").to_string()
}
fn main() {
    let rt = Runtime::new().unwrap();
    let local_tasks = tokio::task::LocalSet::new();

    local_tasks.spawn_local(async {
        println!("local task 1");
        time::sleep(time::Duration::from_secs(2)).await;
        println!("local task 1 done at :{}", now());
    });

    local_tasks.spawn_local(async {
        println!("local task 2 ");
        time::sleep(time::Duration::from_secs(3)).await;
        println!("local task 2 done at :{}", now());
    });

    local_tasks.spawn_local(async {
        println!("local task 4 ");
        time::sleep(time::Duration::from_secs(4)).await;
        println!("local task 4 done at :{}", now());
    });

    local_tasks.spawn_local(async {
        println!("local task 5 ");
        time::sleep(time::Duration::from_secs(6)).await;
        println!("local task 5 done at :{}", now());
    });

    local_tasks.block_on(&rt, async {
        tokio::task::spawn_local(async {
            println!("local task 3 ");
            time::sleep(tokio::time::Duration::from_secs(5)).await;
            println!("local task 3 done at :{}", now());
        })
        .await
        .unwrap();
    });

    rt.block_on(async {
        println!("task in");
        local_tasks.await;
        println!("task done");
    });
}

单看这一段代码,没有运行之前我猜想的运行顺序是。

local task 3
local task 1
local task 2
local task 4
local task 5
local task 1 done at :2022年07月22日 14:08:55
local task 2 done at :2022年07月22日 14:08:56
local task 4 done at :2022年07月22日 14:08:57
local task 3 done at :2022年07月22日 14:08:58
task in
local task 5 done at :2022年07月22日 14:08:59
task done

因为,LocalSet 是从第35行开始执行的。 所以会先输出 local task 3 。

但是实际的输出确是:

local task 1
local task 3
local task 2
local task 4
local task 5
local task 1 done at :2022年07月22日 14:08:55
local task 2 done at :2022年07月22日 14:08:56
local task 4 done at :2022年07月22日 14:08:57
local task 3 done at :2022年07月22日 14:08:58
task in
local task 5 done at :2022年07月22日 14:08:59
task done

local task 1 先被输出,得出结论 ,当我们首次使用 LocalSet::spawn_local() 生成  joinHandel 时,LoaclSet 会将它作为首个需要执行的任务,

当使用 LocalSet::block_on()  插入任务时,并不会将其放到 LocalSet[0] 的位置,而是放在当前位置的下一个可执行位置。

可以将 LoaclSet  当成一把手枪,当我们首次为其添加任务时,它会将子弹上膛,后续添加任务,只是从弹夹底部增加子弹,而使用 LocalSet::block_on()  添加任务时。就是从弹夹上方添加子弹。

tokio

Rust官网

Rust 中文社区

 
posted @ 2022-07-22 14:29  贤云曳贺  阅读(546)  评论(0编辑  收藏  举报