Очень распространенный шаблон в Rust - Arc<Mutex<T>>, где Arc обеспечивает управление памятью, а Mutex обеспечивает безопасный многопоточный доступ к ресурсу. Что еще можно использовать вместо Arc и при каких обстоятельствах?
Когда вы будете использовать Mutex без дуги?
Ответ 1
Arc, конечно, является наиболее распространенным в этом контексте, но существуют другие типы указателей, которые разрешают совместное использование. Основной (и наиболее распространенный, в остальной части Rust) один является общей ссылкой &T. Обычно это не работает с тегами std::thread::spawn 'd, потому что обычно указывает на данные, управляемые каким-то другим потоком, и, как правило, это не 'static (особенно это относится к &Mutex<T>). Однако для создания потока, который может обмениваться данными со своим родителем, можно использовать scoped thread. Например.
extern crate crossbeam;
use std::sync::Mutex;
fn main() {
let data = Mutex::new(vec![0, 1]);
crossbeam::scope(|scope| {
// these run concurrently:
let _guard = scope.spawn(|| {
data.lock().unwrap().push(2);
});
data.lock().unwrap().push(3);
});
println!("{:?}", *data.lock().unwrap());
// one of [0, 1, 2, 3] or [0, 1, 3, 2]
}
Тип data в замыкании, переданном на scope.spawn, на самом деле &Mutex<Vec<i32>> (так как он не имеет ключевого слова move, то закрытие использует стиль захвата по умолчанию: по ссылке).
& и Arc - это те, которые могут достичь такого рода потокобезопасного совместного использования в стандартной библиотеке/языке, но также можно писать типы указателей, которые обеспечивают поточно-безопасный обмен во внешних библиотеках.
Однако, удаляясь от шаблона Pointer<Mutex<...>>, может быть полезно, чтобы мьютекс и разделение разделялись, например. Arc<Vec<Mutex<T>>> позволяет делиться некоторым количеством Mutex<T> без необходимости Arc каждого отдельно, или, может быть, нужно иметь некоторую абстракцию вокруг Mutex, и поэтому оберните ее в struct:
struct Wrapped {
data: Mutex<T>
}
impl Wrapped {
// fancy methods that abstract over `data.lock()`
}
Вероятно, тогда можно увидеть Arc<Wrapped> (или какой-нибудь другой указатель, который разрешает совместное использование).