---
description: Rust Concurrency
alwaysApply: false
---

# Rust Concurrency

Rust prevents data races at compile time. Fearless concurrency doesn't mean you can ignore deadlocks or logic-level races.

## Scoped Threads

```rust
let mut data = vec![1, 2, 3, 4];
thread::scope(|s| {
    let (left, right) = data.split_at_mut(2);
    s.spawn(|| left.iter_mut().for_each(|x| *x *= 2));
    s.spawn(|| right.iter_mut().for_each(|x| *x *= 3));
});
// Both threads finish before scope exits — no Arc, no clone
```

## Shared State (Arc + Mutex)

```rust
let counter = Arc::new(Mutex::new(0));
for _ in 0..10 {
    let counter = Arc::clone(&counter);
    thread::spawn(move || { *counter.lock().unwrap() += 1; });
}
```

## Async/Await (Tokio)

```rust
#[tokio::main]
async fn main() -> Result<()> {
    let listener = TcpListener::bind("0.0.0.0:8080").await?;
    loop {
        let (stream, addr) = listener.accept().await?;
        tokio::spawn(async move {
            if let Err(e) = handle(stream).await { eprintln!("{addr}: {e}"); }
        });
    }
}

// Concurrent execution
let (users, posts) = tokio::join!(fetch_users(), fetch_posts());

// Timeout
tokio::select! {
    result = fetch_data() => handle(result),
    _ = tokio::time::sleep(Duration::from_secs(5)) => bail!("timeout"),
}
```

## Key Rules

- `Send` + `Sync` are auto-traits; `Rc` is not Send — use `Arc` for threads
- Since Rust 1.75: `async fn` in traits works natively
- `tokio::select!` can cancel futures — understand cancellation safety

## Anti-Patterns

```rust
// Never: Hold MutexGuard across .await — deadlock risk
// Never: Spawn tasks without cancellation strategy
// Never: Block in async context — use spawn_blocking for CPU work
// Never: std::sync::Mutex in async code — use tokio::sync::Mutex
```
