m07-concurrency
245
总安装量
242
周安装量
#1112
全站排名
安装命令
npx skills add https://github.com/zhanghandong/rust-skills --skill m07-concurrency
Agent 安装分布
opencode
200
codex
181
gemini-cli
172
claude-code
168
github-copilot
159
amp
101
Skill 文档
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?
Error â Design Question
| Error | Don’t Just Say | Ask 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? |
Thinking Prompt
Before adding concurrency:
-
What’s the workload?
- CPU-bound â threads (std::thread, rayon)
- I/O-bound â async (tokio, async-std)
- Mixed â hybrid approach
-
What’s the sharing model?
- No sharing â message passing (channels)
- Immutable sharing â Arc
- Mutable sharing â Arc<Mutex> or Arc<RwLock>
-
What are the Send/Sync requirements?
- Cross-thread ownership â Send
- Cross-thread references â Sync
- Single-thread async â spawn_local
Trace Up â (MANDATORY)
CRITICAL: Don’t just fix the error. Trace UP to find domain constraints.
Domain Detection Table
| Context Keywords | Load Domain Skill | Key Constraint |
|---|---|---|
| Web API, HTTP, axum, actix, handler | domain-web | Handlers run on any thread |
| 交æ, æ¯ä», trading, payment | domain-fintech | Audit + thread safety |
| gRPC, kubernetes, microservice | domain-cloud-native | Distributed tracing |
| CLI, terminal, clap | domain-cli | Usually single-thread OK |
Example: Web API + Rc Error
"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>>
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?)
| Situation | Trace To | Question |
|---|---|---|
| Send/Sync in Web | domain-web | What’s the state management pattern? |
| Send/Sync in CLI | domain-cli | Is multi-thread really needed? |
| Mutex vs channels | m09-domain | Shared state or message passing? |
| Async vs threads | m10-performance | What’s the workload profile? |
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.
Send/Sync Markers
| Marker | Meaning | Example |
|---|---|---|
Send |
Can transfer ownership between threads | Most 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> |
Quick Reference
| Pattern | Thread-Safe | Blocking | Use When |
|---|---|---|---|
std::thread |
Yes | Yes | CPU-bound parallelism |
async/await |
Yes | No | I/O-bound concurrency |
Mutex<T> |
Yes | Yes | Shared mutable state |
RwLock<T> |
Yes | Yes | Read-heavy shared state |
mpsc::channel |
Yes | Optional | Message passing |
Arc<Mutex<T>> |
Yes | Yes | Shared mutable across threads |
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
Common Errors
| Error | Cause | Fix |
|---|---|---|
E0277 Send not satisfied |
Non-Send in async | Use Arc or spawn_local |
E0277 Sync not satisfied |
Non-Sync shared | Wrap with Mutex |
| Deadlock | Lock ordering | Consistent lock order |
future is not Send |
Non-Send across await | Drop before await |
MutexGuard across await |
Guard held during suspend | Scope guard properly |
Anti-Patterns
| Anti-Pattern | Why Bad | Better |
|---|---|---|
| Arc<Mutex> everywhere | Contention, complexity | Message passing |
| thread::sleep in async | Blocks executor | tokio::time::sleep |
| Holding locks across await | Blocks other tasks | Scope locks tightly |
| Ignoring deadlock risk | Hard to debug | Lock ordering, try_lock |
Async-Specific Patterns
Avoid MutexGuard Across Await
// 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;
Non-Send Types in Async
// 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
Related Skills
| When | See |
|---|---|
| Smart pointer choice | m02-resource |
| Interior mutability | m03-mutability |
| Performance tuning | m10-performance |
| Domain concurrency needs | domain-* |