Chuyển đến nội dung chính

レッスン 8: スマート ポインタと同時実行性

ボックス、Rc、Arc、RefCell、Mutex、RwLock。特性を送信/同期します。 std::thread、メッセージ受け渡し (チャネル)。共有状態の同時実行。データ並列処理にはレーヨン。恐れることのない同時実行。

💻 プログラミング — レッスン 8 レッスン 8: スマート ポインタと同時実行性

Rust: 基本から上級まで

パート 2: 高度な Rust

xdev.asia

1. スマートポインター

use std::rc::Rc;
use std::cell::RefCell;

// Box<T> — heap allocation
let b = Box::new(5);

// Rc<T> — reference counting (single-thread)
let data = Rc::new(vec![1, 2, 3]);
let clone1 = Rc::clone(&data); // Tăng reference count
let clone2 = Rc::clone(&data);
println!("Count: {}", Rc::strong_count(&data)); // 3

// RefCell<T> — interior mutability (runtime borrow check)
let value = RefCell::new(42);
*value.borrow_mut() += 1;
println!("{}", value.borrow()); // 43

// Rc + RefCell — shared mutable data (single-thread)
let shared = Rc::new(RefCell::new(Vec::new()));
let clone = Rc::clone(&shared);
shared.borrow_mut().push(1);
clone.borrow_mut().push(2);

2. スレッドとメッセージパッシング

use std::thread;
use std::sync::mpsc;

fn main() {
    // Spawn thread
    let handle = thread::spawn(|| {
        for i in 1..5 {
            println!("Thread: {}", i);
        }
        42 // Return value
    });

    let result = handle.join().unwrap(); // 42

    // Move data vào thread
    let data = vec![1, 2, 3];
    let handle = thread::spawn(move || {
        println!("{:?}", data);
    });

    // Channel — message passing
    let (tx, rx) = mpsc::channel();
    let tx2 = tx.clone(); // Multiple producers

    thread::spawn(move || {
        tx.send("hello from thread 1").unwrap();
    });

    thread::spawn(move || {
        tx2.send("hello from thread 2").unwrap();
    });

    for msg in rx {
        println!("Received: {}", msg);
    }
}

3. 共有状態 — アーク + ミューテックス

use std::sync::{Arc, Mutex, RwLock};

fn main() {
    // Arc<Mutex<T>> — thread-safe shared mutable state
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];

    for _ in 0..10 {
        let counter = Arc::clone(&counter);
        let handle = thread::spawn(move || {
            let mut num = counter.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }

    for handle in handles {
        handle.join().unwrap();
    }
    println!("Counter: {}", *counter.lock().unwrap()); // 10

    // RwLock — nhiều reader, 1 writer
    let config = Arc::new(RwLock::new(HashMap::new()));
    {
        let mut w = config.write().unwrap();
        w.insert("key", "value");
    }
    {
        let r = config.read().unwrap();
        println!("{:?}", r.get("key"));
    }
}

4. レーヨン — データ並列処理

use rayon::prelude::*;

fn main() {
    let numbers: Vec<i64> = (0..1_000_000).collect();

    // Parallel iterator — tự động chia work
    let sum: i64 = numbers.par_iter().sum();

    // Parallel map + filter
    let results: Vec<i64> = numbers.par_iter()
        .filter(|&&x| x % 2 == 0)
        .map(|&x| x * x)
        .collect();

    // Parallel sort
    let mut data = vec![5, 3, 1, 4, 2];
    data.par_sort();
}
種類シングルスレッドマルチスレッド
所有権ボックスボックス + 送信
共有Rcアーク
内部の可変性RefCellミューテックス / RwLock

次の記事: 非同期RustとTokio。