select! 看起来只是「谁先完成选谁」,但被选掉的那些 Future 会被直接 drop,一半做完的工作就此消失。这篇用一个会丢消息的例子说明「取消安全」是什么,再验证 select! 的公平性与 timeout 的取消行为。
快任务(30ms) 跑完了
快任务(30ms) 被 drop(取消)
慢任务(100ms) 被 drop(取消)
select! 的结果:快任务(30ms)
又过了 150 ms:慢任务既没有跑完也没有再打印,它在 select! 结束时就被取消了Future 取消与 drop 的机制见Future 取消与 Drop。
20 ms 超时,read_then_work 被取消 通道里还剩 [2, 3](消息 1 已经被 read_then_work 取走,取消时丢失了)
100 ms 没有新消息,退出循环 处理了 [1, 2, 3],一条都没丢
通道的另一种用法见异步 Channel。
默认(随机):分支1 4910 次,分支2 5090 次(共 10000) biased; :分支1 10000 次,分支2 0 次
内部 Future 的局部变量被 drop(超时取消了它)
timeout 返回 Err("deadline has elapsed")
未超时的 timeout 返回 Ok("完成")