Hacker News 中文摘要

RSS订阅

取消异步 Rust -- Cancelling async Rust

文章摘要

这篇文章讨论了Rust异步编程中的取消操作问题。作者通过一个从通道循环读取消息的代码示例,展示了在添加超时处理时可能遇到的取消操作复杂性,指出了异步任务取消在Rust中存在的挑战和潜在陷阱。

文章总结

异步Rust中的取消机制解析

本文改编自作者在RustConf 2025上的演讲,探讨了异步Rust中的取消机制问题。以下是主要内容:

引言

作者通过两个看似正确但实际存在问题的代码示例引出主题: 1. 带超时的通道接收循环 2. 带超时的通道发送循环(可能丢失消息)

什么是取消?

在异步Rust中,取消意味着停止正在执行的工作。与同步Rust相比,异步Rust提供了更强大的取消机制: - 同步Rust的取消方式有限(标志位检查、特殊panic、进程终止等) - 异步Rust通过简单地丢弃(drop)Future来实现取消,这是其最大优势但也是最容易出错的部分

Future的本质

Rust中的Future是被动的状态机: - 只有被await或poll时才会执行 - 与其他语言(如JavaScript)不同,Rust的Future在被await前不会自动执行 - 取消Future只需简单地丢弃它

取消安全性与正确性

  • 取消安全性:单个Future被取消时不会产生副作用(如Tokio的sleep是安全的,而MPSC发送是不安全的)
  • 取消正确性:系统在面临取消时保持正确性的全局属性(作者提出的概念)

取消模式分析

常见的导致意外取消的模式: 1. 忘记调用.await 2. 使用try操作(如try_join会在一个失败时取消其他) 3. Tokio的select宏(完成一个分支时会取消其他)

解决方案

虽然目前没有完美的通用解决方案,但有以下缓解措施:

使Future具备取消安全性

  1. 分解MPSC发送操作为"预留位置+发送"两个步骤
  2. 使用writeallbuf替代write_all来处理部分写入情况

避免取消Future

  1. 在select循环中通过pin和可变引用恢复Future而非取消
  2. 使用任务(Task)替代Future来确保代码运行完成

系统性解决方案的挑战

作者指出这是Rust中最不符合其设计理念的部分,现有方案如async drop和线性类型等都面临重大实现挑战。

结论与建议

主要建议包括: - 避免使用Tokio互斥锁 - 重构API使其具备取消安全性 - 确保不安全的Future能够运行完成

作者提供了更多深入讨论的参考资料链接,包括Oxide公司的两份相关设计文档。

评论总结

这篇评论主要围绕异步Rust中的取消机制展开讨论,主要观点如下:

  1. 标题误导性
  • 评论1指出原标题"cancelling async Rust"具有误导性,建议改为"Cancellations in async Rust" "Less clickbaity title: Cancellations in async Rust"
  1. 取消安全性的重要性
  • 评论2和评论4强调了取消安全性的重要性,期待async drop功能的实现 "I really hope we get async drop soon" "The distinction between cancel safety and cancel correctness is really helpful"
  1. await点的潜在风险
  • 评论3提醒await可能成为返回点,不应在需要原子性操作之间使用 "await is always a potential return point...should be avoided"
  1. 具体实现建议
  • 评论5提出了多个关于取消机制的提案,包括强制运行完成和统一取消令牌 "Proposal for unified cancellation between sync and async Rust"
  1. 实际案例讨论
  • 评论6和评论7讨论了超时发送/接收的具体案例和资源耗尽时的处理策略 "send/recv with a timeout example is very interesting" "If the queue is full, the basic options are drop something, block and wait, or panic"
  1. 新手困惑
  • 评论8和评论9表达了对于取消机制理解上的困惑,特别是关于future完成预期的问题 "how to cancel a future after .await had been called" "what else is supposed to happen? If you want the work to finish...spawn a task instead"
  1. 互斥锁问题
  • 评论10特别指出了tokio互斥锁在实际使用中可能带来的问题 "the pain of tokio mutexes...I can totally see making mistakes like this"

不同观点之间保持了平衡,既包含了对取消机制重要性的认可,也反映了对其实现方式和预期行为的困惑。讨论涵盖了从理论概念到具体实现的多个层面。