← ClaudeAtlas

rust-concurrency-synclisted

Fix Rust thread and shared-state concurrency issues — Send/Sync compile errors, choosing a channel type, Arc<Mutex<T>> deadlocks, and mutex poisoning. Use when spawning OS threads, sharing state across threads, a type "cannot be sent between threads safely," or a multi-threaded program hangs/deadlocks.
takurot/rust-skills-comprehensive · ★ 0 · AI & Automation · score 71
Install: claude install-skill takurot/rust-skills-comprehensive
# Rust Threads & Shared State `rust-patterns` has a short `Arc<Mutex<T>>`/channels section for the default idiom. This skill is for when threading **is** the task: a `Send`/`Sync` compile error to fix, a channel type to choose, or a hang/deadlock to diagnose. For `async`/`await` concurrency instead of OS threads, see `rust-async`. ## Threads: spawned vs. scoped `thread::spawn` closures must be `'static` — they **cannot borrow** from the spawning function's stack, because the spawned thread might outlive it: ```rust // Does not compile: closure would borrow `s`, but the thread could outlive `foo` fn foo() { let s = String::from("Hello"); thread::spawn(|| dbg!(s.len())); } ``` Two fixes: - **Own the data**: `move ||` the value into the closure, or clone/wrap it (`Arc`) if it's needed elsewhere too. - **`thread::scope`**: guarantees every thread spawned inside the scope closure is joined before the scope returns, so borrows from the enclosing stack frame are sound: ```rust thread::scope(|scope| { scope.spawn(|| dbg!(s.len())); // borrowing `s` is fine here }); ``` Normal borrowing rules still apply inside a scope: one thread may hold `&mut`, or any number may hold `&`, never both at once. **`thread::spawn` doesn't keep `main` alive** — if `main` returns first, unjoined spawned threads are simply cut off (not even guaranteed to finish). Capture the `JoinHandle` and call `.join()` if you need the thread's work to complete, or its return value: ```rust let