一键导入
concurrency
Concurrency Patterns guidance for Fortress Rollback. Use when Choosing concurrency primitives, Mutex vs RwLock decisions, channel patterns.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Concurrency Patterns guidance for Fortress Rollback. Use when Choosing concurrency primitives, Mutex vs RwLock decisions, channel patterns.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Crate Publishing guidance for Fortress Rollback. Use when Publishing to crates.io, version bumps, release checklist.
Changelog Practices guidance for Fortress Rollback. Use when Writing CHANGELOG entries, deciding what to document.
Design Decision Log Pattern guidance for Fortress Rollback. Use when Architectural decisions, design alternatives, superseding prior choices.
Repository-wide engineering policy and project context for Fortress Rollback. Use when implementing, diagnosing, reviewing, testing, documenting, or releasing changes in this repository.
GitHub Actions Best Practices guidance for Fortress Rollback. Use when Writing GitHub Actions workflows, CI debugging, actionlint, caching.
Workspace Organization guidance for Fortress Rollback. Use when Organizing workspace, splitting crates, module structure decisions.
| name | concurrency |
| description | Concurrency Patterns guidance for Fortress Rollback. Use when Choosing concurrency primitives, Mutex vs RwLock decisions, channel patterns. |
Is data accessed from multiple threads?
No -> No synchronization needed
Yes -> Read-only after init?
Yes -> Arc<T>
No -> What access pattern?
Mostly reads, rare writes -> RwLock<T>
Frequent writes, short sections -> Mutex<T>
Single atomic value -> Atomic* types
Producer-consumer -> Channels
| Primitive | Use When | Avoid When |
|---|---|---|
Mutex<T> | Short critical sections, frequent writes | Long-held locks, read-heavy |
RwLock<T> | Read-heavy, occasional writes | Write-heavy (reader starvation) |
Atomic* | Single values, lock-free algorithms | Complex multi-field updates |
Arc<T> | Shared ownership, immutable data | Mutable data (use Arc<Mutex<T>>) |
mpsc::channel | Producer-consumer, message passing | Low-latency requirements |
crossbeam::channel | High-performance channels | Simple use cases |
// Use parking_lot::Mutex -- no poisoning, so .lock() returns the guard directly
let value = {
let guard = counter.lock();
*guard // copy value
}; // lock released
expensive_operation(); // other threads can proceed
// Use parking_lot::RwLock -- no poisoning, no .unwrap() needed
let needs_write = {
let guard = self.data.read();
needs_update(&guard)
}; // read lock MUST drop here
if needs_write {
let mut guard = self.data.write();
if needs_update(&guard) { update(&mut guard); } // double-check
}
fn try_connect(&self) -> bool {
self.state.compare_exchange(
Disconnected as u8, Connecting as u8,
Ordering::AcqRel, Ordering::Acquire,
).is_ok()
}
enum Command { Process(Data), Shutdown }
fn worker(rx: mpsc::Receiver<Command>) {
loop {
match rx.recv() {
Ok(Command::Process(d)) => process(d),
Ok(Command::Shutdown) | Err(_) => break,
}
}
}
If a Drop guard mutates thread-local state, make it explicitly !Send and !Sync
with a private PhantomData<Rc<()>> marker. Add compile_fail doctests that try
to move and borrow the guard across threads so the thread-affinity contract is
checked by doctest CI. If removing owned resources from a RefCell-backed
thread-local stack, return the removed value and drop it after releasing the
borrow so destructors can safely re-enter telemetry/logging. In guard Drop,
use LocalKey::try_with rather than with so TLS teardown cannot panic.
| Ordering | Use Case |
|---|---|
Relaxed | Counters where order doesn't matter |
Acquire | Load that must see prior Release stores |
Release | Store that must be visible to Acquire loads |
AcqRel | Read-modify-write (fetch_add, compare_exchange) |
SeqCst | Total ordering needed, or when in doubt |
try_lock for timeout-based preventionRUSTFLAGS="-Z sanitizer=thread" cargo +nightly testparking_lot is faster than std::sync (smaller Mutex, no poisoning)crossbeam (SegQueue, etc.)| Pitfall | Fix |
|---|---|
No Arc for shared ownership | Arc::clone() before thread::spawn |
| Poisoned mutexes | Use parking_lot::Mutex (no poisoning) |
Rc across threads | Rc is not Send; use Arc |
| Busy-wait without yield | std::hint::spin_loop() or condvar |
std::sync::Mutex held across .await | Use tokio::sync::Mutex |
parking_lot over std::sync