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 0..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:?}");
}
This slide should take about 5 minutes.
Arcは“Atomic Reference Counted“の略で、アトミック操作を利用するという点で、Rcがスレッド安全になったバージョンのようなものです。Arc<T>はCloneを実装します。このことはTがCloneを実装するしないに関係ありません。TがSendとSyncの両方を実装している場合で、かつその場合に限り、Arc<T>は両者を実装します。Arc::clone()にはアトミック操作のコストがかかります。ただ、その後は、Tの利用に関するコストはかかりません。- 参照サイクルに気をつけてください。
Arcには参照サイクルを検知するためのガベージコレクタはありません。std::sync::Weakが役立ちます。