拉斯特一个非常普遍的模式是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>
(或其他一些允许共享的指针).