m07-concurrency

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Concurrency

并发

Layer 1: Language Mechanics
第一层:语言机制

Core Question

核心问题

Is this CPU-bound or I/O-bound, and what's the sharing model?
Before choosing concurrency primitives:
  • What's the workload type?
  • What data needs to be shared?
  • What's the thread safety requirement?

这是CPU密集型还是I/O密集型工作负载?数据共享模型是什么?
在选择并发原语之前:
  • 工作负载类型是什么?
  • 需要共享哪些数据?
  • 线程安全要求是什么?

Error → Design Question

错误 → 设计问题

ErrorDon't Just SayAsk Instead
E0277 Send"Add Send bound"Should this type cross threads?
E0277 Sync"Wrap in Mutex"Is shared access really needed?
Future not Send"Use spawn_local"Is async the right choice?
Deadlock"Reorder locks"Is the locking design correct?

错误不要直接说而是要问
E0277 Send"添加Send约束"该类型是否需要跨线程传递?
E0277 Sync"用Mutex包裹"真的需要共享访问吗?
Future not Send"使用spawn_local"异步是正确的选择吗?
死锁"重新排序锁"锁的设计是否正确?

Thinking Prompt

思考提示

Before adding concurrency:
  1. What's the workload?
    • CPU-bound → threads (std::thread, rayon)
    • I/O-bound → async (tokio, async-std)
    • Mixed → hybrid approach
  2. What's the sharing model?
    • No sharing → message passing (channels)
    • Immutable sharing → Arc<T>
    • Mutable sharing → Arc<Mutex<T>> or Arc<RwLock<T>>
  3. What are the Send/Sync requirements?
    • Cross-thread ownership → Send
    • Cross-thread references → Sync
    • Single-thread async → spawn_local

在引入并发之前:
  1. 工作负载类型是什么?
    • CPU密集型 → 使用线程(std::thread、rayon)
    • I/O密集型 → 使用异步(tokio、async-std)
    • 混合型 → 使用混合方案
  2. 数据共享模型是什么?
    • 无需共享 → 使用消息传递(channels)
    • 不可变共享 → 使用Arc<T>
    • 可变共享 → 使用Arc<Mutex<T>>或Arc<RwLock<T>>
  3. Send/Sync的要求是什么?
    • 跨线程所有权转移 → 需要Send
    • 跨线程引用共享 → 需要Sync
    • 单线程异步 → 使用spawn_local

Trace Up ↑ (MANDATORY)

向上追溯 ↑(强制要求)

CRITICAL: Don't just fix the error. Trace UP to find domain constraints.
重要提示:不要只修复错误,要向上追溯以找到领域约束。

Domain Detection Table

领域检测表

Context KeywordsLoad Domain SkillKey Constraint
Web API, HTTP, axum, actix, handlerdomain-webHandlers run on any thread
交易, 支付, trading, paymentdomain-fintechAudit + thread safety
gRPC, kubernetes, microservicedomain-cloud-nativeDistributed tracing
CLI, terminal, clapdomain-cliUsually single-thread OK
上下文关键词加载领域技能核心约束
Web API、HTTP、axum、actix、handlerdomain-web处理器可在任意线程运行
交易、支付、trading、paymentdomain-fintech审计 + 线程安全
gRPC、kubernetes、microservicedomain-cloud-native分布式追踪
CLI、terminal、clapdomain-cli通常单线程即可

Example: Web API + Rc Error

示例:Web API + Rc错误

"Rc cannot be sent between threads" in Web API context
    ↑ DETECT: "Web API" → Load domain-web
    ↑ FIND: domain-web says "Shared state must be thread-safe"
    ↑ FIND: domain-web says "Rc in state" is Common Mistake
    ↓ DESIGN: Use Arc<T> with State extractor
    ↓ IMPL: axum::extract::State<Arc<AppConfig>>
Web API场景下出现"Rc cannot be sent between threads"错误
    ↑ 检测到:"Web API" → 加载domain-web技能
    ↑ 发现:domain-web要求"共享状态必须是线程安全的"
    ↑ 发现:domain-web指出"状态中使用Rc"是常见错误
    ↓ 设计方案:结合State提取器使用Arc<T>
    ↓ 实现:axum::extract::State<Arc<AppConfig>>

Generic Trace

通用追溯流程

"Send not satisfied for my type"
    ↑ Ask: What domain is this? Load domain-* skill
    ↑ Ask: Does this type need to cross thread boundaries?
    ↑ Check: m09-domain (is the data model correct?)
SituationTrace ToQuestion
Send/Sync in Webdomain-webWhat's the state management pattern?
Send/Sync in CLIdomain-cliIs multi-thread really needed?
Mutex vs channelsm09-domainShared state or message passing?
Async vs threadsm10-performanceWhat's the workload profile?

出现"Send not satisfied for my type"错误
    ↑ 询问:这属于什么领域?加载对应的domain-*技能
    ↑ 询问:该类型是否需要跨线程边界?
    ↑ 检查:m09-domain(数据模型是否正确?)
场景追溯至问题
Web场景下的Send/Sync问题domain-web状态管理模式是什么?
CLI场景下的Send/Sync问题domain-cli真的需要多线程吗?
Mutex vs channels选择m09-domain用共享状态还是消息传递?
异步 vs 线程选择m10-performance工作负载特征是什么?

Trace Down ↓

向下落地 ↓

From design to implementation:
"Need parallelism for CPU work"
    ↓ Use: std::thread or rayon

"Need concurrency for I/O"
    ↓ Use: async/await with tokio

"Need to share immutable data across threads"
    ↓ Use: Arc<T>

"Need to share mutable data across threads"
    ↓ Use: Arc<Mutex<T>> or Arc<RwLock<T>>
    ↓ Or: channels for message passing

"Need simple atomic operations"
    ↓ Use: AtomicBool, AtomicUsize, etc.

从设计到实现:
"需要为CPU工作实现并行"
    ↓ 选择:std::thread或rayon

"需要为I/O实现并发"
    ↓ 选择:结合tokio使用async/await

"需要跨线程共享不可变数据"
    ↓ 选择:Arc<T>

"需要跨线程共享可变数据"
    ↓ 选择:Arc<Mutex<T>>或Arc<RwLock<T>>
    ↓ 或者:使用channels进行消息传递

"需要简单的原子操作"
    ↓ 选择:AtomicBool、AtomicUsize等

Send/Sync Markers

Send/Sync标记

MarkerMeaningExample
Send
Can transfer ownership between threadsMost types
Sync
Can share references between threads
Arc<T>
!Send
Must stay on one thread
Rc<T>
!Sync
No shared refs across threads
RefCell<T>
标记含义示例
Send
可在线程间转移所有权大多数类型
Sync
可在线程间共享引用
Arc<T>
!Send
必须保留在单个线程中
Rc<T>
!Sync
不可在线程间共享引用
RefCell<T>

Quick Reference

快速参考

PatternThread-SafeBlockingUse When
std::thread
YesYesCPU-bound parallelism
async/await
YesNoI/O-bound concurrency
Mutex<T>
YesYesShared mutable state
RwLock<T>
YesYesRead-heavy shared state
mpsc::channel
YesOptionalMessage passing
Arc<Mutex<T>>
YesYesShared mutable across threads
模式线程安全是否阻塞使用场景
std::thread
CPU密集型并行
async/await
I/O密集型并发
Mutex<T>
共享可变状态
RwLock<T>
读多写少的共享状态
mpsc::channel
可选消息传递
Arc<Mutex<T>>
跨线程共享可变状态

Decision Flowchart

决策流程图

What type of work?
├─ CPU-bound → std::thread or rayon
├─ I/O-bound → async/await
└─ Mixed → hybrid (spawn_blocking)

Need to share data?
├─ No → message passing (channels)
├─ Immutable → Arc<T>
└─ Mutable →
   ├─ Read-heavy → Arc<RwLock<T>>
   └─ Write-heavy → Arc<Mutex<T>>
   └─ Simple counter → AtomicUsize

Async context?
├─ Type is Send → tokio::spawn
├─ Type is !Send → spawn_local
└─ Blocking code → spawn_blocking

工作负载类型是什么?
├─ CPU密集型 → std::thread或rayon
├─ I/O密集型 → async/await
└─ 混合型 → 混合方案(spawn_blocking)

需要共享数据吗?
├─ 不需要 → 消息传递(channels)
├─ 不可变共享 → Arc<T>
└─ 可变共享 →
   ├─ 读多写少 → Arc<RwLock<T>>
   └─ 写多读少 → Arc<Mutex<T>>
   └─ 简单计数器 → AtomicUsize

处于异步上下文?
├─ 类型是Send → tokio::spawn
├─ 类型是!Send → spawn_local
└─ 阻塞代码 → spawn_blocking

Common Errors

常见错误

ErrorCauseFix
E0277
Send
not satisfied
Non-Send in asyncUse Arc or spawn_local
E0277
Sync
not satisfied
Non-Sync sharedWrap with Mutex
DeadlockLock orderingConsistent lock order
future is not Send
Non-Send across awaitDrop before await
MutexGuard
across await
Guard held during suspendScope guard properly

错误原因修复方案
E0277
Send
未满足
异步中使用了非Send类型使用Arc或spawn_local
E0277
Sync
未满足
共享了非Sync类型用Mutex包裹
死锁锁的顺序问题保持一致的锁顺序
future is not Send
await跨越了非Send类型在await前释放该类型
MutexGuard
跨越await
挂起期间持有锁守卫合理限制锁守卫的作用域

Anti-Patterns

反模式

Anti-PatternWhy BadBetter
Arc<Mutex<T>> everywhereContention, complexityMessage passing
thread::sleep in asyncBlocks executortokio::time::sleep
Holding locks across awaitBlocks other tasksScope locks tightly
Ignoring deadlock riskHard to debugLock ordering, try_lock

反模式危害更佳方案
到处使用Arc<Mutex<T>>竞争激烈、复杂度高消息传递
异步中使用thread::sleep阻塞执行器tokio::time::sleep
持有锁守卫跨越await阻塞其他任务严格限制锁的作用域
忽略死锁风险难以调试锁顺序规范、使用try_lock

Async-Specific Patterns

异步特定模式

Avoid MutexGuard Across Await

避免MutexGuard跨越await

rust
// Bad: guard held across await
let guard = mutex.lock().await;
do_async().await;  // guard still held!

// Good: scope the lock
{
    let guard = mutex.lock().await;
    // use guard
}  // guard dropped
do_async().await;
rust
// 错误示例:守卫在await期间被持有
let guard = mutex.lock().await;
do_async().await;  // 守卫仍被持有!

// 正确示例:限制锁的作用域
{
    let guard = mutex.lock().await;
    // 使用守卫
}  // 守卫被释放
do_async().await;

Non-Send Types in Async

异步中的非Send类型

rust
// Rc is !Send, can't cross await in spawned task
// Option 1: use Arc instead
// Option 2: use spawn_local (single-thread runtime)
// Option 3: ensure Rc is dropped before .await

rust
// Rc是!Send类型,无法在已生成的任务中跨越await
// 方案1:改用Arc
// 方案2:使用spawn_local(单线程运行时)
// 方案3:确保在.await前释放Rc

Related Skills

相关技能

WhenSee
Smart pointer choicem02-resource
Interior mutabilitym03-mutability
Performance tuningm10-performance
Domain concurrency needsdomain-*
场景参考内容
智能指针选择m02-resource
内部可变性m03-mutability
性能调优m10-performance
领域并发需求domain-*