Rust:是否可以用Rayon更新共享数组?

ymdaylpp  于 2022-12-19  发布在  其他
关注(0)|答案(1)|浏览(189)

我有一个u8的数组,我将用一种复杂的方式来划分它。
有没有可能从多个人造丝任务中更新它呢?有点像这样:

let mut pixels = vec![0; w * h];

 
    rayon::scope(|s| {

        s.spawn(move |_s| {
            my_fn(&mut pixels);
        }
    }

顺便说一句,我知道into_par_iter,但我不能提前划分像素。
即,划分方案将是递归的,并且将取决于一些任务的结果。
仅供参考,我将来回传递有关像素的元数据,这将影响pixelsmy_fn的哪个部分将被处理,这里没有显示。
我得到了这个错误,它阻止我以后借用pixels

|                                 ------ variable moved due to use in closure
...
999 |             write_image(&pixels)
    |                                   ^^^^^^^ value borrowed here after move

我应该给予这个设计吗,还是有办法让它成功?

des4xlb0

des4xlb01#

使用原子数组。如果你从来没有在不同的线程中修改过相同的元素,你可以安全地使用Ordering::Relaxed(我认为这是免费的?我不是这方面的Maven)。
如果你无法改变Vec的创建,你可以将&mut [int]转换为&mut [Atomic],因为它们保证有相同的布局。在夜间,你可以使用from_mut_slice()。在稳定状态下,你可以用很少的不安全代码创建它:

fn from_mut_slice(v: &mut [i32]) -> &mut [AtomicI32] {
    unsafe { &mut *(v as *mut [i32] as *mut [AtomicI32]) }
}

如果你想避免这个代价(假设有代价),你可以使用UnsafeCell,如果你从来没有从不同的线程访问相同的像素(但是作为一个不安全代码的用户,证明这一点的责任在你身上)。注意UnsafeCell不是Sync,所以你需要用一个实现Sync的自定义类型 Package 它;在夜间,您可以使用SyncUnsafeCell

相关问题