拉斯特一个非常普遍的模式是Arc<Mutex<T>>,这里Arc提供了内存管理,并Mutex提供安全的多线程访问资源.还有什么可以代替Arc,在什么情况下使用?
huo*_*uon 25
Arc当然这是此上下文中最常见的一种,但还有其他指针类型允许共享.主要(最常见的,在Rust的其余部分)一个是共享引用&T.这通常不适用于std::thread::spawn'd个线程,因为它通常指向由某个其他线程控制的数据,因此通常不会'static(特别是当它是a时&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]
}
Run Code Online (Sandbox Code Playgroud)
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()`
}
Run Code Online (Sandbox Code Playgroud)
然后可能会看到Arc<Wrapped>(或其他一些允许共享的指针).