任务指标
这一部分是本卷的重点,讲任务主线。代码全在 src/task.rs 里:3 673 行中三分之二是文档注释,真正的算法只有 instrument_poll 和 State::on_wake 两个函数,加起来 170 行。难的不是代码,而是这几个时间戳到底在量什么:哪段等待算「空闲」、哪段算「排队」,和 tokio 自己的调度对不对得上。
- Instrumented 与 instrument_poll:
instrument时记下的东西;Instrumented的四个字段;instrument_poll逐段走一遍:首次 poll 延迟从instrument()被调用算起,一次 poll 取三次Instant::now()、做十来次SeqCst原子操作;Stream只给默认的Instrumented<T, TaskMonitor>实现。 - 包装 waker:空闲与排队怎么算:
State实现ArcWake,on_wake用compare_exchange(0, now)只记第一次唤醒;四个实验:两次唤醒、poll 里唤醒自己、yield_now、嵌套的Instrumented,各自的时间落进哪一列。 - TaskMetrics 与派生指标:
RawMetrics的原子计数器怎么变成 19 个字段;没有单独的 poll 总数;在途数;最大空闲的两个原子变量;derived_metrics!宏和 10 个派生指标,均值除以 0 得 0、两个比率除以 0 得 NaN;两个阈值。 - TaskMonitorCore 与 FutureMonitor:0.4.9 拆出不带
Arc的TaskMonitorCore,const fn构造,可以放进static;0.5.2 新增FutureMonitor,一个 future 一份指标,排队时间要外层任务先打开publish_scheduling_delay,借线程局部变量传进来。
flowchart TB inst["instrument:包一层"] --> poll["instrument_poll:三个时间戳"] poll --> waker["包装 waker:记唤醒时刻"] waker --> poll poll --> raw["RawMetrics:一组 AtomicU64"] raw --> tm["TaskMetrics:19 个字段"] tm --> derived["10 个派生指标"] inst --> core["TaskMonitorCore:可放进 static"] inst --> fm["FutureMonitor:一个 future 一份"]
第 1、2 章是全卷的地基:后面的运行时指标只是读 tokio 的计数器,而任务指标的每个字段,都可以对照这两章里的三个时间戳来理解它量的是哪一段。
💬 关联讨论
发起讨论加载中...