主要观点:在开发Crucible时,反复遇到看似“不可能”的低概率恐慌,追踪到是Tokio 运行时管理已启动任务的边缘情况导致。通过一个简单示例展示问题,系统中有两个任务,生产者向工作者发送数字并检查结果,工作者加 1 后返回。正常情况下工作者在生产者运行时不会停止,但 Tokio 运行时在关闭时会以任意顺序停止任务,导致生产者在等待回复时读取到None
而恐慌。在 10,000 次循环测试中,在response_rx.recv().await.unwrap()
处有 26 次恐慌,默认的多线程运行时容易触发此问题,而单线程运行时不会,tokio::test
默认使用单线程运行时,此问题在单元测试中可能不明显,在系统的集成测试和程序退出时都出现过。Tokio 以任意顺序停止任务本身没错,但可考虑在停止所有任务后再丢弃任务数据以避免此类问题,不过其可行性取决于 Tokio 的内部实现。
关键信息:
- 开发过程中遇到低概率恐慌及追踪到的原因。
- 展示的两个任务系统及其数据流向。
- 测试代码及 10,000 次循环测试中的恐慌次数。
- 不同运行时对问题的影响。
- Tokio 运行时关于任务停止的相关文档说明。
重要细节:
- 工作者任务和生产者任务的具体实现代码。
- 运行时关闭时任务停止的顺序及导致的问题。
- 测试代码中设置停止标志及运行时关闭的位置。
- Tokio 运行时在不同模式下对问题的表现。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。