Languages: Python C C++ Go Java Ruby Rust Perl R ← Full TOC

← Rust Index

🔒 std::thread — Threads, Arc, Mutex, mpsc channels

Rust guarantees thread safety at compile time. Share data with Arc<Mutex<T>>. Communicate between threads with std::sync::mpsc channels. The compiler rejects data races.

Docs: doc.rust-lang.org

📋 Types, Functions & Methods

NameSignatureDescription
thread::spawnfn spawn<F,T>(f: F) -> JoinHandle<T>Spawn new OS thread
handle.joinfn join(self) -> thread::Result<T>Wait for thread and return its result
thread::sleepfn sleep(dur: Duration)Sleep current thread for duration
thread::currentfn current() -> ThreadReturn handle to current thread
thread::available_parallelismfn available_parallelism() -> Result<NonZeroUsize>Number of available CPU cores
Arc::newfn new(data: T) -> Arc<T>Create atomically-reference-counted pointer
arc.clonefn clone(&self) -> Arc<T>Increment refcount, return new Arc
Mutex::newfn new(t: T) -> Mutex<T>Create mutual exclusion wrapper
mutex.lockfn lock(&self) -> LockResult<MutexGuard<'_,T>>Acquire lock; blocks until available
MutexGuardstruct MutexGuard<'a, T>Auto-unlocks when dropped (RAII)
RwLockstruct RwLock<T>Reader-writer lock (multiple readers OR one writer)
rwlock.readfn read(&self) -> LockResult<RwLockReadGuard<'_,T>>Acquire shared read lock
rwlock.writefn write(&self) -> LockResult<RwLockWriteGuard<'_,T>>Acquire exclusive write lock
mpsc::channelfn channel<T>() -> (Sender<T>, Receiver<T>)Create multi-producer single-consumer channel
sender.sendfn send(&self, t: T) -> Result<(),SendError<T>>Send value to channel
receiver.recvfn recv(&self) -> Result<T, RecvError>Block until value received
receiver.try_recvfn try_recv(&self) -> Result<T, TryRecvError>Non-blocking receive attempt
mpsc::sync_channelfn sync_channel<T>(bound: usize) -> (SyncSender<T>, Receiver<T>)Bounded channel
AtomicUsizestruct AtomicUsizeLock-free atomic integer
atomic.fetch_addfn fetch_add(&self, val: usize, order: Ordering) -> usizeAtomic addition
atomic.loadfn load(&self, order: Ordering) -> usizeAtomic load
atomic.storefn store(&self, val: usize, order: Ordering)Atomic store
Barrierstruct BarrierSynchronize N threads at a rendezvous point
Condvarstruct CondvarCondition variable for thread coordination

💡 Example

Save as main.rs in a Cargo project and run with cargo run.

use std::sync::{Arc, Mutex, mpsc};
use std::thread;
use std::time::Duration;

fn main() {
    // --- Shared state with Arc<Mutex<T>> ---
    let counter  = Arc::new(Mutex::new(0u64));
    let mut handles = vec![];
    for _ in 0..8 {
        let counter = Arc::clone(&counter);
        handles.push(thread::spawn(move || {
            for _ in 0..1000 { *counter.lock().unwrap() += 1; }
        }));
    }
    for h in handles { h.join().unwrap(); }
    println!("Counter: {} (expected 8000)", *counter.lock().unwrap());

    // --- mpsc Channel ---
    let (tx, rx) = mpsc::channel::<String>();
    let tx2 = tx.clone();
    thread::spawn(move || {
        for i in 0..5 { tx.send(format!("P1-{}", i)).unwrap(); thread::sleep(Duration::from_millis(5)); }
    });
    thread::spawn(move || {
        for i in 0..5 { tx2.send(format!("P2-{}", i)).unwrap(); thread::sleep(Duration::from_millis(5)); }
    });
    let mut messages: Vec<String> = (0..10).map(|_| rx.recv().unwrap()).collect();
    messages.sort();
    println!("Messages: {:?}", messages);

    // --- Atomic counter ---
    use std::sync::atomic::{AtomicUsize, Ordering};
    let atomic  = Arc::new(AtomicUsize::new(0));
    let mut hs  = vec![];
    for _ in 0..4 {
        let a = Arc::clone(&atomic);
        hs.push(thread::spawn(move || { for _ in 0..250 { a.fetch_add(1, Ordering::Relaxed); } }));
    }
    for h in hs { h.join().unwrap(); }
    println!("Atomic: {} (expected 1000)", atomic.load(Ordering::SeqCst));
}
// cargo run

← std::collections  |  🏠 Index  |  Option & Result →