我无法理解来自 C++ 的 Rust 并发模型。
我的数组将使用另一个定义索引的数组同时访问。例如(伪代码):
let indices = [1, 2, 3, 4, 1, 2, 3, 2, 1, 1, 3, 2, 2];
let mut arr = [1, 2, 3, 4, 5, 6, 7, 8, 10];
indices.iter_par().for_each(|x| {
arr[x] += x;
});
在 C++ 中,我会保护 arr
中的每个索引。使用锁或使用原子访问。我怎样才能在 Rust 中做同样的事情?
编辑
我还有另一个相关问题。
如何将普通数组作为可变数组传递到并行迭代器中,并确保不会发生竞争条件?
let indices = [1, 2, 3, 4, 5, 6, 7, 8];
let mut arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
indices.iter_par().for_each(|x| {
arr[x] = some_function(x);
});
最佳答案
如果您需要为每个项目锁定,我不知道并行执行此操作的意义是什么,但您可以使用要改变的数组周围的 Mutex
来实现此目的:
use rayon::prelude::*;
use std::sync::Mutex;
fn main() {
let indices = [1, 2, 3, 4, 1, 2, 3, 2, 1, 1, 3, 2, 2];
let arr = Mutex::new([1, 2, 3, 4, 5, 6, 7, 8, 10]);
indices.par_iter().for_each(|&x| {
let mut arr = arr.lock().unwrap();
arr[x] += x;
});
}
编辑
根据评论,您可以让每个元素都是原子的:
use rayon::prelude::*;
use std::sync::atomic::{AtomicUsize, Ordering};
fn main() {
let indices = [1, 2, 3, 4, 1, 2, 3, 2, 1, 1, 3, 2, 2];
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 10]
.iter()
.map(|&n| AtomicUsize::new(n))
.collect::<Vec<_>>();
indices.par_iter().for_each(|&x| {
arr[x].fetch_add(x, Ordering::SeqCst);
});
}
关于arrays - 使用索引数组并行写入数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64423043/