SuperAPI AI 工具集

rust-async-concurrency

编程与开发

查看项目

更新于 10-26 16:23

技能介绍

用途

该技能面向编写异步 Rust 代码的场景,包括:派生任务、跨任务或线程共享状态、在通道与互斥锁之间做选择,以及处理异步 trait 中出现的 Send 约束错误。它还专门覆盖“trait 中的 async fn”的 Send 问题——解释为什么 trait 中的 async fn 默认不产生 Send future,以及如何绕过该限制。

范围外:HTTP 服务结构(路由、提取器、中间件)由 rust-web-backend 负责;仅同步的所有权与借用问题属于 rust-core-language。

主要能力

运行时选择

  • tokio:事实标准,几乎所有异步 crate(axum、sqlx、reqwest、tonic)都以其为目标,默认选择。
  • async-std:小众,实际处于维护模式,不建议用于新项目。
  • smol:小众,适合小型或嵌入式场景,仅用于受限或嵌入式环境。

除非有硬性约束,否则默认使用 tokio。

关键规则

  • 优先使用 std::sync::Mutex,它更快。仅当守卫必须跨 .await 持有时才使用 tokio::sync::Mutex;否则应缩小守卫作用域,使其析构函数在 await 之前运行。
  • Arc<Mutex<T>> 不是默认选择,需先分析竞争情况。读多写少用 RwLock;简单计数器用原子类型;本身是异步的工作用任务加消息传递。
  • 不要丢弃你关心的 JoinHandle——被丢弃的 tokio::spawn 句柄会静默吞掉任务的 panic/错误。应 .await 它,或用 JoinSet/tracing 暴露失败。
  • 重同步工作使用 spawn_blocking——CPU 密集型循环或阻塞式 I/O(std 文件、阻塞式数据库驱动)若在异步工作线程上运行会拖垮运行时,应将其卸载。
  • 跨 .await 的 Send——在 await 点之间持有的所有内容对 tokio::spawn 而言都必须是 Send。std::sync::MutexGuard 不是 Send,跨 await 持有它是编译错误(而 Send 的 async-mutex 守卫则会死锁)。

参考指南

概念:

  • 运行时与任务(runtime-and-tasks.md):spawn、JoinHandle、JoinSet、spawn_blocking、'static 约束。
  • 共享状态(shared-state.md):在 Mutex、RwLock、原子类型、actor 任务之间选择。
  • 通道(channels.md):选择 mpsc / oneshot / broadcast / watch。
  • 异步 trait(async-traits.md):trait 中的 async fn 及 Send 约束问题。

模板:

  • task-patterns.md:并发任务、JoinSet、actor 模式、spawn_blocking。
  • graceful-shutdown.md:取消、关闭信号、排空任务。

使用方式

强制智能体工作流

编写异步代码前,并行执行:

  • fuse-ai-pilot:explore-codebase——查找代码库中已有的运行时、通道和锁模式。
  • fuse-ai-pilot:research-expert——通过 Context7/Exa 验证当前 tokio/crate API(异步 API 变动频繁)。
  • mcp__context7__query-docs——拉取你所触及原语的确切签名。

编写完成后,运行 fuse-ai-pilot:sniper。

快速参考

缩小守卫作用域,不要跨 .await 持有:

// GOOD: lock released before the await
{
    let mut db = state.lock().unwrap();
    db.insert(key, value);
} // guard dropped here
do_async_work().await;

→ 参见 shared-state.md

按形态选择通道:

// one value back to a caller → oneshot
// many producers, one consumer → mpsc
// fan-out same value to all → broadcast
// latest-value-only state → watch

→ 参见 channels.md

最佳实践

应做:

  • 选择锁之前先测量竞争情况;优先选择最合适的最廉价原语。
  • 暴露任务失败:.await 句柄,或用 JoinSet 收集它们。
  • 将重同步工作移到 spawn_blocking。

不应做:

  • 条件反射地使用 tokio::sync::Mutex——它内部包装了一个同步互斥锁,很少能提升吞吐量。
  • 对结果或 panic 重要的 tokio::spawn 采用即发即忘。
  • 假设 trait 中的 async fn 会给你 Send future——它不会(见 async-traits.md)。

适用场景

  • 编写异步 Rust 代码,需要派生任务或管理任务生命周期。
  • 需要在任务或线程之间共享状态,并在 Mutex、RwLock、原子类型、actor 任务之间做选择。
  • 需要在 mpsc、oneshot、broadcast、watch 等通道之间做选择。
  • 遇到异步 trait 的 Send 约束错误,需要理解原因和绕过方法。
  • 需要处理优雅关闭、取消和任务排空。

限制

  • 不覆盖 HTTP 服务结构(路由、提取器、中间件),该部分由 rust-web-backend 负责。
  • 不覆盖仅同步的所有权与借用问题,该部分属于 rust-core-language。
  • 资料中未提供该技能的安装命令、收费方式、价格或平台信息。

来源(已验证)

  • tokio.rs/tokio/tutorial——共享状态、派生、通道(获取于 2026-07-05)
  • rust-lang.github.io/async-fundamentals-initiative/roadmap.html——AFIT 状态
  • crates.io——tokio 1.53.1(获取时 2026-09-27 为当前版本)