动手
前面各部分是读 tokio-metrics 的源码,这一部分反过来:不依赖它,只用标准库把任务主线的骨架写一遍。写完再回头看,on_wake 为什么用 compare_exchange(0, now)、区间最大值为什么只能 swap(0)、Stream 为什么要单独实现,都会变成你自己做过的选择。
- 从零写一个 Instrumented:约 170 行的库加一个演示程序。
std::task::Wake实现包装 waker,compare_exchange只记第一次唤醒;每次 poll 记排队、换 waker、量 poll 时长并按阈值分快慢;Intervals记住上一次的读数做差。用忙等 5ms 的任务验证慢 poll,用唤醒自己的任务验证排队,和 tokio-metrics 在同一组任务上对照:排队均值相差不到 1µs。yield_now在两边都记不成排队,原因和 包装 waker 里讲的一样。
flowchart TB wake["WakeState:实现 Wake"] --> cas["compare_exchange:只记第一次"] inst["Instrumented:包一层"] --> sched["poll 开头:swap 取出唤醒时刻,记排队"] sched --> swap["存下真 waker,换成自己的"] swap --> poll["poll 内层,量时长,分快慢"] poll --> cnt["Counters:一组 AtomicU64"] cas --> sched cnt --> iv["Intervals:记住上一次,做差"] iv --> cmp["和 tokio-metrics 对照"]
💬 关联讨论
发起讨论加载中...