如何删除值周围的“MutexGuard”?

BoK*_*enU 4 rust

我正在尝试使用 ndarray 作为异步过程来进行线性代数等。我使用 Rust 的 tokio 和 ndarray 创建了以下代码。

use std::sync::{Arc, Mutex};
use ndarray::prelude::*;
use futures::future::join_all;

fn print_type_of<T>(_: &T) {
    println!("{}", std::any::type_name::<T>())
}


#[tokio::main]
async fn main() {
    let db = Arc::new(Mutex::new(array![0,0,0,0,0,0,0,0]));
    let mut handels = vec![];

    for i in 0..8 {
        let db = db.clone();
        let unchange_array = unchange_array.clone();
        handels.push(tokio::spawn(async move{
            print(i, db).await;
        }));
    }
    join_all(handels).await;
    let array = Arc::try_unwrap(db).unwrap();
    let array = array.lock().unwrap();
    print_type_of(&array);  // -> std::sync::mutex::MutexGuard<ndarray::ArrayBase<ndarray::data_repr::OwnedRepr<u32>, ndarray::dimension::dim::Dim<[usize; 1]>>>

}

async fn print(i: u32, db: Arc<Mutex<Array1<u32>>>) {
    let unchange = unchange.to_owned();
    let mut tmp = 0;
    // time-consuming process
    for k in 0..100000000 {
        tmp = k; 
    }
    tmp += i;
    let mut db = db.lock().unwrap();
    db.fill(i);
    println!("{:?}", unchange);
    print_type_of(&db);
}
Run Code Online (Sandbox Code Playgroud)

我想将数据更改std::sync::mutex::MutexGuard<ndarray::ArrayBase<OwnedRepr<u32>, Dim<[usize; 1]>>>ndarray::ArrayBase<OwnedRepr<u32>, Dim<[usize; 1]>>.

我怎样才能做到这一点?

Jmb*_*Jmb 9

你不能。这就是 的全部要点MutexGuard:如果您可以从 中取出数据MutexGuard,那么您将能够创建一个可以在不锁定互斥体的情况下访问的引用,从而破坏了首先拥有互斥体的整个目的。

根据您真正想做的事情,以下解决方案之一可能适用于您:

  • 大多数时候,您不需要从互斥体中取出数据:MutexGuard<T>实现Deref<Target=T>and DerefMut<Target=T>,因此您可以MutexGuard在任何需要使用 a&T或 a 的地方使用&mut T。请注意,如果您将代码更改为 callprint_type_of(&*array)而不是print_type_of(&array),它将打印内部类型

  • 如果确实需要,您可以使用 来从自身Mutex(而不是MutexGuard)中取出数据into_inner,这会消耗互斥体,确保其他人无法访问它:

let array = Arc::try_unwrap(db).unwrap();
let array = array.into_inner().unwrap();
print_type_of(&array);  // -> ndarray::ArrayBase<ndarray::data_repr::OwnedRepr<u32>, ndarray::dimension::dim::Dim<[usize; 1]>>
Run Code Online (Sandbox Code Playgroud)