rust-concurrency
Skill8 starsChanged 43 days agoApache-2.0View on GitHub
Design, implement, diagnose, and test Rust concurrency and parallelism with threads, Send and Sync, locks, atomics, channels, Tokio, Rayon, Crossbeam, bounded backpressure, actor ownership, task supervision, graceful shutdown, runtime diagnostics, and Loom model tests. Use when users ask about shared state, deadlocks, async tasks, CPU parallelism, high concurrency, daemon resource budgets, slow consumers, worker pools, lock-free structures, or concurrent correctness.
We split this skill into the rules it gives an agent
1 rule. 0 are common, 1 is distinctive, and 0 are very specific to this project.
0
Common
Most of the 6 edited versions we read keep these.
1
Distinctive
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 26
Read-heavy snapshots, sharded maps, caches, and alternative locks when measurements justify them
“Common” is measured: kept by at least 6 in 10 of the 6 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Rust Concurrency
Based on the standard library
std::thread,std::sync, andstd::sync::atomicmodules, along with the Async Book. Use when designing, debugging, load-testing, or reviewing threaded and async Rust code; cancellation, task ownership, lock scope, runtime sizing, queues, overload management, message passing, hand basic ownership to rust-stable and unsafe invariants to rust-unsafe-ffi.
Capability Boundaries
✅ Strengths
- OS threads (
thread::spawn,Builder,join, scoped threads, move closures) - Synchronization primitives (Mutex, RwLock, Barrier, Condvar, OnceLock, LazyLock)
- Atomic types (AtomicBool/Isize/Usize, load/store/fetch_add/swap/compare_exchange, Ordering)
- Channels (
mpsc: multi-producer single-consumer, Receiver, Sender) Send/Synctrait system (automatic derivation and manual implementation)- async/await syntax with the Future trait
- Tokio runtime (
tokio::main,tokio::spawn, select!, JoinSet) - Async I/O foundations (
tokio::fs,tokio::net,tokio::io) - Bounded queues, backpressure, slow consumers, concurrency limits and overload strategies
- Task supervision, connection lifecycles, cancellation safety and graceful shutdown
- CPU-bound data parallelism and dedicated Rayon pools
- Crossbeam channels, queues, work-stealing deques, and scoped threads
- Read-heavy snapshots, sharded maps, caches, and alternative locks when measurements justify them
- Loom model checking and Tokio runtime diagnostics
⚠️ Prerequisites
- Understanding Rust ownership model (
rust-stable)
❌ Inapplicable Scenarios
- Unsafe code concurrent execution → use
rust-unsafe-ffiskill - Basic ownership/borrowing → use
rust-stableskill
When to Use
- "Process data with multiple threads"
- "How to write async/await"
- "Tokio runtime usage"
- "Shared data between threads"
- "Avoid data races"
- "Rate limiting and graceful shutdown in high-concurrency services"
- "Tokio channel backlog or slow consumers"
Data Privacy
This skill does not collect, store, or transmit any user data.
I. OS Threads
use std::thread;
let handle = thread::spawn(move || {
println!("Hello from thread!");
});
handle.join().unwrap();
// Thread with configuration
let builder = thread::Builder::new()
.name("worker".into())
.stack_size(1024 * 1024);
let handle = builder.spawn(move || { /* ... */ }).unwrap();
// scoped threads (1.63+)
let mut v = vec![1, 2, 3];
thread::scope(|s| {
s.spawn(|| {
v.push(4); // borrow, no move required
});
});
println!("{v:?}"); // v remains usableII. Synchronization Primitives
use std::sync::{Arc, Mutex, RwLock, Barrier, OnceLock, LazyLock};
// Mutex (mutual exclusion lock)
let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0..10 {
let counter = Arc::clone(&counter);
handles.push(thread::spawn(move || {
let mut num = counter.lock().unwrap();
*num += 1;
}));
}
// RwLock (read-write lock)
let data = Arc::new(RwLock::new(vec![1, 2, 3]));
{
let read = data.read().unwrap();
assert_eq!(read.len(), 3);
} // Drop the read guard before taking the write lock.
data.write().unwrap().push(4);
// OnceLock (thread-safe lazy initialization)
static CONFIG: OnceLock<String> = OnceLock::new();
let config = CONFIG.get_or_init(|| load_config());
// LazyLock
static CACHE: LazyLock<HashMap<String, Data>> = LazyLock::new(HashMap::new);III. Atomic Operations
use std::sync::atomic::{
AtomicBool, AtomicU64, Ordering
};
static COUNTER: AtomicU64 = AtomicU64::new(0);
COUNTER.fetch_add(1, Ordering::SeqCst);
static READY: AtomicBool = AtomicBool::new(false);
READY.store(true, Ordering::Release);
let ready = READY.load(Ordering::Acquire);
// Ordering levels
// Relaxed — no ordering guarantees (only atomicity)
// Release — write visibility
// Acquire — read visibility
// AcqRel — both reads and writes visible
// SeqCst — global sequential order (strongest, but not automatically default; explicit Ordering required for atomic operations)IV. Channels
use std::sync::mpsc;
let (tx, rx) = mpsc::channel();
thread::spawn(move || {
tx.send(1).unwrap();
tx.send(2).unwrap();
});
for received in rx {
println!("Got: {received}");
}
// Multi-producer scenario
let (tx, rx) = mpsc::channel();
let tx1 = tx.clone();V. async/await
use tokio::time;
async fn do_work(id: u32) -> &'static str {
time::sleep(time::Duration::from_secs(1)).await;
println!("Task {id} done");
"ok"
}
#[tokio::main]
async fn main() {
// Concurrent execution
let (r1, r2) = tokio::join!(do_work(1), do_work(2));
// select!
tokio::select! {
result = do_work(1) => println!("task1: {result}"),
result = do_work(2) => println!("task2: {result}"),
}
// tokio::spawn
let handle = tokio::spawn(do_work(3));
handle.await.unwrap();
}VI. Send / Sync
// T is Send if its ownership can be transferred across threads
// &T is Sync if it can be shared references across threads
// Types that are both Send + Sync: Arc<Mutex<T>>, i32, &'static str
// !Send types: Rc<T>, *const T
// !Sync types: RefCell<T>, Cell<T>
// Manual implementations are unsafe contracts. Do not add them merely to
// satisfy a compiler error; prove aliasing, lifetime, and thread-safety first.VII. Select the Execution Model
| Workload | Default starting point | Avoid |
| Many readiness-driven network operations | Tokio tasks with bounded admission | One task or buffer per unbounded input |
| CPU-heavy independent items | Rayon parallel iterators or a dedicated pool | Running long CPU work on Tokio workers |
| Blocking filesystem, FFI, or legacy APIs | Bounded spawn_blocking submissions or a dedicated pool | Treating Tokio's blocking queue as backpressure |
| Synchronous MPMC messaging or work stealing | Crossbeam channels, queues, or deques | Selecting lock-free structures without measurement |
| Small shared state with short critical sections | std::sync locks | Holding guards across .await or callbacks |
| Read-mostly immutable snapshots | ArcSwap after profiling | A concurrent map for every read-heavy value |
| Shared keyed mutable state | Sharded ownership or DashMap after contention tests | Multi-key operations without an atomicity design |
| Expiring concurrent cache | Moka with explicit capacity and eviction policy | An unbounded map called a cache |
Tokio is primarily for I/O concurrency; Rayon is for CPU parallelism. Mixing them requires an explicit handoff, independent concurrency limits, and shutdown ownership. Read Concurrency Tool Selection before introducing a third-party primitive.
Workflow
- Classify the workload — separate readiness-driven I/O, CPU parallelism, blocking calls, synchronization, and durable messaging before selecting a runtime or primitive.
- Write concurrency budgets — define maximum connections, in-flight tasks, queue capacity, item size, timeouts, memory, CPU pools, and shutdown deadlines.
- Determine state ownership — prefer partitioned or single-writer ownership; share state only with an explicit atomicity and lock-ordering contract.
- Select communication semantics — choose bounded point-to-point, request/reply, latest-value, lossy broadcast, or durable replay deliberately; specify queue-full and receiver-lag behavior.
- Supervise execution — retain task or thread handles, propagate failure, contain panic, prevent orphan work, and define caller-cancellation behavior.
- Design graceful shutdown — stop admission, close producers, publish cancellation, join within a deadline, flush required state, and return unresolved failures.
- Measure before tuning — record throughput, p50/p95/p99 latency, queue depth, saturation, task poll time, wakeups, lock wait, CPU, allocations, and RSS.
- Verify the model — test overload and cancellation, use Loom for small synchronization state machines, and use tokio-console or tracing for runtime stalls. Read Concurrency Testing and Diagnostics.
Gotchas
- Mutex::lock() returns a
MutexGuard; do not await before dropping to avoid deadlocks - tokio::spawn's Future must be both Send and 'static; non-Send references will cause compilation errors
- Async closures capture ownership differently than regular closures — use the move keyword explicitly for transfer of state
- Cancelled Futures in select! branches do not execute cleanup logic directly before dropping
- Atomic Ordering is not relational semantics; misuse of Relaxed can lead to unexpected memory ordering issues
- broadcast lag is distinct from normal success paths; must choose between discarding, rebuilding snapshots, disconnecting slow consumers, or persistently replaying events
- max_blocking_threads limits only the number of blocking threads and does not provide backpressure for submission queues; high-cost tasks require Semaphore or bounded queues
- JoinSet returns results in completion order; if API requires input ordering, carry indices through to restore sequence during aggregation
DashMap,parking_lot,ArcSwap, and lock-free queues change semantics as well as performance; benchmarks do not replace invariant review- Loom sees only synchronization performed through Loom-aware types and can suffer state-space explosion; keep models small and deterministic
- Rayon work may outlive the async caller unless cancellation and pool ownership are designed explicitly
On-Demand Resources
- Concurrency Examples
- Type & Tool Quick Reference
- Concurrency Tool Selection: Read when choosing Tokio, Rayon, Crossbeam, locks, sharded maps, snapshots, or caches.
- Concurrency Testing and Diagnostics: Read when proving synchronization correctness, diagnosing runtime stalls, or load-testing overload and shutdown.
- Production Async Service Patterns: Read when designing actors, backpressure, slow consumers, task supervision, runtime configuration, and shutdown protocols.
examples/golden-threads/: CI-built scoped thread examples
Official References
Other versions7 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 7
- huiali/rust-skills★ 47same name
- botirkhaltaev/botir-skills★ 4same name
- inference-gateway/skills★ 3same name
- Lu1sDV/skillsmd★ 2same name
- adxptived/Rust-Skills★ 1same name
- owenlamont/skills★ 1same name
- Dankosik/rust-cli-skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository32 other files it gives its agents.
- openspec-apply-changeSkill
- openspec-archive-changeSkill
- openspec-exploreSkill
- openspec-proposeSkill
- rust-api-designSkill
- rust-by-exampleSkill
- rust-cargo-buildSkill
- rust-cliSkill
- rust-code-reviewSkill
- rust-crate-discoverySkill
- rust-databaseSkill
- rust-dependenciesSkill
- rust-documentationSkill
- rust-embeddedSkill
- rust-http-clientSkill
- rust-java-migrationSkill
- rust-java-migration-testingSkill
- rust-lombok-macrosSkill
- rust-macrosSkill
- rust-module-layoutSkill
- rust-observabilitySkill
- rust-performanceSkill
- rust-semverSkill
- rust-stableSkill
- rust-stdlibSkill
- rust-style-clippySkill
- rust-testingSkill
- rust-uniffi-buildingSkill
- rust-unsafe-ffiSkill
- rust-web-securitySkill
- rust-webSkill
- rust-workspaceSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

