真正理解 Future,最好的办法是自己写一个。这篇从零写一个定时器 Future 和一个 join 组合子,用 poll 计数和耗时验证它们的行为,并复现两个最常见的错误:忘记保存 waker 与只保存第一次的 waker。
编译:成功
运行(退出码 0):
等 100 ms 的 Timer:实际 100 ms,executor 总共 poll 了 2 次(第一次 Pending,被 wake 后第二次 Ready)Waker 的细节见Waker 唤醒机制;Pin 见Pin 与 Unpin。
编译:成功
运行(退出码 0):
顺序 await 两个 100 ms:总耗时约 200 ms,poll 3 次
join2 同时等两个 100 ms:总耗时约 100 ms,poll 3 次,结果 (A, B)
join2 的 150 ms 与 50 ms:总耗时约 160 ms(取最长的),poll 3 次(50 ms 的先完成、150 ms 的后完成) 编译:成功
运行(退出码 0):
600 ms 过去了,Timer 仍然没有完成:poll 时没保存 waker,到点后 wake 的是 None,executor 永远睡着 编译:成功
运行(退出码 0):
80 ms 到点后:waker1 被唤醒了吗? false waker2 被唤醒了吗? true(Timer 每次 poll 都覆盖了保存的 waker,所以只有最新的 waker2 被通知)