Arc

Arc<T> は読み取り専用の共有アクセスをArc::cloneにより可能にします:

use std::sync::Arc;
use std::thread;

fn main() {
    let v = Arc::new(vec![10, 20, 30]);
    let mut handles = Vec::new();
    for _ in 1..5 {
        let v = Arc::clone(&v);
        handles.push(thread::spawn(move || {
            let thread_id = thread::current().id();
            println!("{thread_id:?}: {v:?}");
        }));
    }

    handles.into_iter().for_each(|h| h.join().unwrap());
    println!("v: {v:?}");
}
  • Arc は“Atomic Reference Counted“の略で、アトミック操作を利用するという点で、Rcがスレッド安全になったバージョンのようなものです。
  • Arc<T>Clone を実装します。このことはTCloneを実装するしないに関係ありません。TSendSyncの両方を実装している場合で、かつその場合に限り、Arc<T> は両者を実装します。
  • Arc::clone()にはアトミック操作のコストがかかります。ただ、その後は、Tの利用に関するコストはかかりません。
  • 参照サイクルに気をつけてください。Arc には参照サイクルを検知するためのガベージコレクタはありません。
    • std::sync::Weak が役立ちます。