【发布时间】:2020-10-19 07:41:28
【问题描述】:
我无法理解来自 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);
});
【问题讨论】:
-
“在 C++ 中,我会简单地用锁保护 arr 中的每个索引或使用原子访问。我如何在 rust 中做同样的事情?” - 你也可以这样做在 Rust 中使用
Mutex<i32>s 或AtomicI32s 数组(如果需要) -
我遇到的问题是 rust 中的互斥锁的功能。与 C++ 不同,rust mutex 封装了它保护的数据。我需要对 arr 进行单独保护以进行并行访问或类似的东西。使整个数组原子化是一种可能性,但不是首选。
-
@Adam 不,互斥体和原子提供了内部可变性,因此您根本不需要保护数组本身:Rust 的借用检查器不会让您同时读取数组(访问或更新其项目)并更新它(添加新项目),因此它充当“静态”RWLock。虽然如果您需要更复杂的东西,您当然可以将数组包装在 RWLock 中,在运行时工作。
-
虽然请注意,预处理
indices以计算每个索引处的增量数可能是一个更好的主意,然后您可以将其压缩到您的数组并使用类似par_iter_mut为了增加每个索引正确的次数,而不需要在您自己的代码中进行任何同步。
标签: arrays concurrency rust parallel.foreach