2

这个问题类似于 使用索引数组并行写入数组, 除了我保证索引是唯一的。

let indices = [1, 4, 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);
});

有没有办法在人造丝中实现这一目标?也许我应该以某种方式使用unsafe,因为显然借用检查器无法验证索引的唯一性。

4

1 回答 1

1

您当然可以使用 来做到这一点unsafe,例如通过发送指向线程的指针:

// thin wrapper over pointer to make it Send/Sync
#[derive(Copy, Clone)]
struct Pointer(*mut u32);
unsafe impl Send for Pointer {}
unsafe impl Sync for Pointer {}

let indices = [1, 4, 7, 8];
let mut arr = [1u32, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let arr_ptr = Pointer(arr.as_mut_ptr());

indices.into_par_iter().for_each(move |x| {
    // safety:
    // * `indices` must be unique and point inside `arr`
    // * `place` must not leak outside the closure
    // * no element of `array` that is in `indices` may be accessed by
    //   some other thread while this is running
    let place = unsafe { &mut *{arr_ptr}.0.add(x) };
    *place = some_function(x);
});

但我会保留这种东西,只作为最后的手段。一旦你在你的代码库中引入了这样的 ad-hoc unsafe,你永远不知道你什么时候会犯错误并使你的程序容易受到随机崩溃和损坏的影响。

于 2022-01-25T12:09:34.197 回答