我们知道Rust
的异步是以task
的调度来构建的。task
作为抽象在语言层面的调度单元。
那如果想要观测其的调度执行有没有办法呢?。
有的!异步runtime
库tokio
就有个tokio-console
可以实现对异步调度的观测和分析,其对了解调度的机制和性能分析都很有帮助。
环境设置
其调度的观测是需要依赖程序段添加 console-subscriber
来上报runtime
的调度信息,然后由命令行程序tokio-console
进行数据的统计展示。
这个功能还属于unstable,需要引入时做一些设置。
具体来说,需要在引入tokio
时启用tracing
, 如
1 | [dependencies] |
异步代码main
中也需要初始化console_subscriber
1 |
|
代码运行时需要加上编译参数: RUSTFLAGS="--cfg tokio_unstable" cargo run
也可以在项目根目录用.cargo/config.toml
全局配置, 如
1 | [build] |
这样同时运行tokio-console
就能观测异步任务的调度了。
(cargo install tokio-console
可以安装)
代码改造
以之前《Rust并发控制之Semaphore-两线程交替打印》代码来观测为例
修改部分详见代码注释:
1 | use std::{sync::Arc, time::Duration}; |
观测效果
得到的观测结果如下,可以切换为task
视图(按键t
)和resource
视图(按键r
):
task
对于task
能看到调度时间(Total, Busy, Sched, Idle
),次数(Polls
),状态(state
)等。
想详细了解时间可以看看这篇博客:task-scheduled-time-in-console
左右按键可以选择列,上下按键可以选择行,回车会展开对应行详情, 比如task-t2
里边能看到相应waker的一些信息,也会有更细粒度的时间分布图
比较容易发现耗时不正常的task
。
resource
对于resource
, 能看到执行了哪些类型的异步操作
详情中是对这个操作不同时间调用的详细展开。
比如t2
中semaphore_wait.acquire
的三次调用
本文代码详见tokio-play
想查看更多异步观测的例子建议查看下官方的例子
如有疑问,请文末留言交流或邮件:newbvirgil@gmail.com 本文链接 : https://newbmiao.github.io/2024/01/26/rust-tokio-task-tracing.html