patternrusttokioMajor
Arc<Mutex<T>>: sharing mutable state across async tasks and threads
Viewed 0 times
ArcMutexshared statethread safetyclonelockRwLockasync Mutex
Error Messages
Problem
Sharing mutable state between tokio tasks or OS threads requires both reference counting (so multiple owners exist) and locking (to prevent data races).
Solution
Wrap mutable shared data in Arc<Mutex<T>> and clone the Arc before moving into each task:
use std::sync::{Arc, Mutex};
use tokio;
#[tokio::main]
async fn main() {
let counter = Arc::new(Mutex::new(0u32));
let mut handles = vec![];
for _ in 0..10 {
let counter = Arc::clone(&counter); // cheap reference count bump
let h = tokio::spawn(async move {
let mut guard = counter.lock().unwrap();
*guard += 1;
});
handles.push(h);
}
for h in handles { h.await.unwrap(); }
println!("Final: {}", *counter.lock().unwrap()); // 10
}
// In async code, prefer tokio::sync::Mutex to avoid blocking threads
use tokio::sync::Mutex as AsyncMutex;
let shared = Arc::new(AsyncMutex::new(Vec::<String>::new()));Why
Arc provides thread-safe reference counting so multiple tasks can share ownership. Mutex provides exclusive access via locking. Together they satisfy Rust's thread safety invariants (Send + Sync).
Gotchas
- std::sync::Mutex blocks the OS thread when waiting — inside tokio tasks use tokio::sync::Mutex instead
- Holding a MutexGuard across an .await point will deadlock or cause 'future is not Send' errors
- Prefer RwLock when reads vastly outnumber writes — allows multiple concurrent readers
Revisions (0)
No revisions yet.