我正在尝试使用 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]>>.
我怎样才能做到这一点?
你不能。这就是 的全部要点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)
| 归档时间: |
|
| 查看次数: |
5461 次 |
| 最近记录: |