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

Ale*_*nor 25 rust

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

  • 链接是死的,根据他们的包装页面:"这个箱子已经过时了.Crossbeam项目目前处于过渡期.我们正在重写epoch垃圾收集器,以及其他几个实用程序并添加新结构.要遵循进展,请在这里查看项目中的其他包装箱.转换完成后,将更新此包以使用新代码." (2认同)