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() 添加任务时。就是从弹夹上方添加子弹。
本文来自博客园,作者:贤云曳贺,转载请注明原文链接:https://www.cnblogs.com/SantiagoZhang/p/16505647.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话