你什么时候会使用没有 Arc 的互斥锁? [英] When would you use a Mutex without an Arc?

查看:33
本文介绍了你什么时候会使用没有 Arc 的互斥锁?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

An extremely common pattern in Rust is Arc<Mutex<T>>, where Arc provides the memory management, and Mutex provides safe multi-threaded access to the resource. What else could be used in place of Arc, and under what circumstances?

推荐答案

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

Arc is of course the most common one in this context, but there are other pointer types that allow sharing. The major (and most common, in the rest of Rust) one is the shared reference &T. This normally doesn't work with std::thread::spawn'd threads, because it generally points to data controlled by some other thread, and is hence usually not 'static (particularly so when it is a &Mutex<T>). However, one can use a scoped thread to create a thread that can share data with its parent. E.g.

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]
}

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

The type of data in the closure passed to scope.spawn is in fact &Mutex<Vec<i32>> (since it doesn't have the move keyword the closure is using the default capturing style: by reference).

&Arc 是可以在标准库/语言中实现这种线程安全共享的两种,但也可以编写指针类型,提供外部库中的线程安全共享.

& and Arc are the two that can achieve this sort of thread-safe sharing in the standard library/language, but one can also write pointer types that offer thread-safe sharing in external libraries.

然而,远离 Pointer<Mutex<...>> 模式,将互斥体和共享分开可能很有用,例如Arc>> 允许共享一定数量的 Mutex 而不必 Arc每个单独的,或者可能想要对 Mutex 进行一些抽象,然后将其包装在 struct 中:

However, moving away from the Pointer<Mutex<...>> pattern, it can be useful to have the mutex and the sharing separated, e.g. Arc<Vec<Mutex<T>>> allows one to share some number of Mutex<T>'s without having to Arc each one individually, or maybe one wants to have some abstraction around a Mutex, and so wrap it in a struct:

struct Wrapped {
    data: Mutex<T>,
}
impl Wrapped {
    // fancy methods that abstract over `data.lock()`
}

然后人们可能会看到Arc(或其他一些允许共享的指针).

One would likely then see Arc<Wrapped> (or some other pointer that allows sharing).

这篇关于你什么时候会使用没有 Arc 的互斥锁?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆