你何时会使用没有Arc的Mutex?

时间:2015-10-14 03:51:19

标签: rust

Rust中非常常见的模式是Arc<Mutex<T>>,其中Arc提供内存管理,Mutex提供对资源的安全多线程访问。还有什么可以代替Arc,以及在什么情况下?

1 个答案:

答案 0 :(得分:23)

Arc当然是此上下文中最常见的一种,但还有其他指针类型允许共享。主要(在Rust的其余部分中最常见)一个是共享引用&T。这通常不适用于std::thread::spawn个线程,因为它通常指向由其他线程控制的数据,因此通常不是'static(尤其是当它是&Mutex<T>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] } )。但是,可以使用scoped thread创建可与其父级共享数据的线程。 E.g。

data

传递给scope.spawn的闭包中&Mutex<Vec<i32>>的类型实际上是move(因为它没有&关键字,因此闭包正在使用默认捕获样式:通过引用)。

ArcPointer<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>

然后可能会看到Radgrid1.Rebind(或其他允许共享的指针)。