rust - 什么时候使用没有 Arc 的 Mutex?

标签 rust

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

最佳答案

Arc在这种情况下当然是最常见的一种,但是还有其他允许共享的指针类型。主要的(也是最常见的,在 Rust 的其余部分)是共享引用 &T .这通常不适用于 std::thread::spawn 'd 线程,因为它通常指向由其他线程控制的数据,因此通常不是 'static (特别是当它是 &Mutex<T> 时)。但是,可以使用 scoped thread创建一个可以与其父级共享数据的线程。例如

use crossbeam; // 0.7.3
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);
    })
    .unwrap();

    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> (或其他一些允许共享的指针)。

关于rust - 什么时候使用没有 Arc 的 Mutex?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33116317/

相关文章:

rust - 如何根据编译功能标志为枚举添加生命周期

rust - &diesel::MysqlConnection 未实现特性 diesel::Connection

rust - 如何从Rust(火箭)HTTP端点返回JSON?

rust - 如何将 Iterator<String> 作为 Iterator<&str> 传递?

rust - Rust 如何处理引用计数类型的 "island of isolation"(引用循环)场景?

rust - 如何以方便的方式对齐堆上的内存(在一个盒子里)?

rust - 如何从 Visual Studio Code 启动 Rust 应用程序?

rust - 为什么 rustc 不运行我的简单 "hello world"程序?

rust - 添加不相关的通用参数会触发奇怪的生命周期错误

string - 从字符串创建字符切片的滑动窗口迭代器