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
が役立ちます。