使用索引数组并行写入数组 编辑

问题描述

我无法理解来自C ++的Rust中的并发模型。

我的数组将使用另一个定义索引的数组并发访问。例如(伪代码):

let indices = [1,2,3,4,1,2];
let mut arr = [1,5,6,7,8,10];

indices.iter_par().for_each(|x| {
    arr[x] += x;
});

在C ++中,我将使用锁保护arr中的每个索引或使用原子访问。我如何在Rust中做同样的事情?

编辑

我还有另一个相关问题。

我如何将可变的普通数组传递到并行迭代器中,我可以确定不会出现竞争条件?

let indices = [1,8];
let mut arr = [1,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];
    let arr = Mutex::new([1,5,6,7,8,10]);

    indices.par_iter().for_each(|&x| {
        let mut arr = arr.lock().unwrap();
        arr[x] += x;
    });
}

playground

编辑

基于注释,您可以使每个元素都是原子的:

use rayon::prelude::*;
use std::sync::atomic::{AtomicUsize,Ordering};

fn main() {
    let indices = [1,2];
    let arr = [1,10]
        .iter()
        .map(|&n| AtomicUsize::new(n))
        .collect::<Vec<_>>();

    indices.par_iter().for_each(|&x| {
        arr[x].fetch_add(x,Ordering::SeqCst);
    });
}

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...