- Home
- Skills
- Zhanghandong
- Rust Skills
- M07 Concurrency
m07-concurrency_skill
- Shell
565
GitHub Stars
2
Bundled Files
2 months ago
Catalog Refreshed
4 months ago
First Indexed
Readme & install
Copy the install command, review bundled files from the catalogue, and read any extended description pulled from the listing source.
Installation
Preview and clipboard use veilstrat where the catalogue uses aiagentskills.
npx veilstrat add skill zhanghandong/rust-skills --skill m07-concurrency- comparison.md7.3 KB
- SKILL.md6.2 KB
Overview
This skill guides Rust developers through concurrency and async decisions, error diagnosis, and safe implementations. It helps determine whether to use threads, async, or message passing, and shows how to trace errors like E0277 to design constraints before applying fixes. It emphasizes domain-aware choices and avoiding common anti-patterns.
How this skill works
It inspects error contexts and workload characteristics to recommend appropriate primitives (std::thread, rayon, tokio, channels, Arc/Mutex/RwLock, atomics). It traces UP to domain constraints (web, CLI, fintech, cloud-native) to decide thread-safety requirements and traces DOWN to map design choices to concrete implementations. It provides patterns for avoiding deadlocks, holding locks across await points, and handling non-Send/!Sync types.
When to use it
- When you see E0277 Send/Sync or "future is not Send" errors
- When deciding between CPU-bound parallelism and I/O-bound async
- When sharing data across threads or tasks
- When diagnosing deadlocks, race conditions, or contention
- When migrating single-threaded code (Rc/RefCell) to multi-threaded contexts
Best practices
- Classify workload: CPU-bound → threads/rayon; I/O-bound → async/await (tokio)
- Trace UP to domain constraints before changing types or adding bounds
- Prefer message passing (channels) when no shared mutable state is needed
- Use Arc<T> for immutable shared data; Arc<Mutex<T>> or Arc<RwLock<T>> for mutable sharing, but minimize scope of locks
- Avoid holding Mutex/RwLock guards across .await; drop guards before awaiting
- Use spawn_blocking for CPU work in async runtimes and spawn_local only for truly non-Send futures
Example use cases
- Fixing "Rc cannot be sent between threads" in a web handler by tracing to domain-web and switching to Arc<AppState>
- Resolving "future is not Send" by dropping non-Send values before await or using spawn_local on a single-thread runtime
- Choosing rayon or thread::spawn for CPU-heavy batch processing, with atomics for simple counters
- Replacing global Arc<Mutex<T>> contention with channel-based message passing in a high-concurrency service
- Preventing deadlock by enforcing consistent lock ordering and using try_lock for diagnostics
FAQ
No. Ask whether the type actually needs to cross thread boundaries. Tracing the domain and ownership model can show that single-threaded or spawn_local solutions are more appropriate.
When do I prefer channels over locks?
Use channels when components can exchange messages without shared mutable state. Channels reduce contention and often simplify reasoning compared to pervasive Arc<Mutex<T>>.
How do I handle non-Send types in async code?
Either convert to Send-safe types (Arc instead of Rc), ensure non-Send values are dropped before await, or run the task on a single-threaded runtime with spawn_local.