Arc (Atomic Reference Counting или атомарный подсчет ссылок) в некотором роде представляет аналог Rc, который
также позволяет нескольким владельцам, в том числе потокам, совместно владеть некоторыми общими данными. Однако отличие от Rc указатель Arc
потокобезопасен и нацелен на те ситуации, когда общие данные могут использовать в нескольких потоках. Наглядный пример расположения в памяти вектора, для которого с помощью Arc установлен ряд владельцев-потоков:
Рассмотрим следующий пример:
use std::sync::Arc;
use std::thread;
fn main() {
let data = Arc::new(vec![1, 2, 3, 4, 5]); // определяем общие данные
// создаем две копии общих данных
let clone1 = Arc::clone(&data);
let clone2 = Arc::clone(&data);
// запускаем 2 потока, которые обращаются к общим данным
let thread1 = thread::spawn(move || {
let sum: i32 = clone1.iter().sum();
println!("Thread 1 - Sum of Data: {}", sum);
});
let thread2 = thread::spawn(move || {
let len: usize = clone2.len();
println!("Thread 2 - Length of Data: {}", len);
});
// ждем завершения потоков
thread1.join().unwrap();
thread2.join().unwrap();
} // data, clone1, clone2 и потоки выходят из области видимости; память освобождается
Здесь указатель Arc используется для безопасного совместного использования вектора [1, 2, 3, 4, 5] между несколькими потоками. Два потока (thread1 и thread2) создаются для выполнения операций с общими данными. Когда все ссылки на данные (data, clone1 и clone2) и потоки выходят за пределы области видимости, память автоматически освобождается. Консольный вывод:
Thread 1 - Sum of Data: 15 Thread 2 - Length of Data: 5
Arc особенно ценен в многопоточном программировании, обеспечивая безопасный доступ к данным несколькими потоками. Его подсчет ссылок гарантирует, что обращение к его ресурсам и их освобождение обрабатываются потокобезопасным способом, что делает его отличным выбором для общих данных в многопоточных средах.