Rust

Многопоточность: Arc, Mutex и каналы

Algonexys · 07.08.2026 · 👁 0

Разделяемое состояние между потоками и передача сообщений — оба идиоматичных способа.

Код

use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{mpsc, Arc, Mutex};
use std::thread;

fn main() {
    // 1. Разделяемое состояние: Arc для владения, Mutex для доступа
    let counter = Arc::new(Mutex::new(0));
    let handles: Vec<_> = (0..8)
        .map(|_| {
            let counter = Arc::clone(&counter);
            thread::spawn(move || {
                for _ in 0..1000 {
                    *counter.lock().unwrap() += 1;
                }
            })
        })
        .collect();

    for handle in handles {
        handle.join().unwrap();
    }
    println!("Счётчик: {}", *counter.lock().unwrap());   // 8000

    // 2. Атомарный счётчик — быстрее Mutex для простых чисел
    let atomic = Arc::new(AtomicUsize::new(0));
    thread::scope(|s| {
        for _ in 0..4 {
            let atomic = Arc::clone(&atomic);
            s.spawn(move || { atomic.fetch_add(1, Ordering::Relaxed); });
        }
    });
    println!("Атомарный: {}", atomic.load(Ordering::SeqCst));

    // 3. Передача сообщений через канал
    let (tx, rx) = mpsc::channel();
    for id in 0..3 {
        let tx = tx.clone();
        thread::spawn(move || tx.send(format!("результат потока {id}")).unwrap());
    }
    drop(tx);   // закрываем последнего отправителя, иначе rx будет ждать вечно

    for message in rx {
        println!("{message}");
    }
}