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 @   贤云曳贺  阅读(674)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示