本人小白。以往 rust 中多线程需求都能按照建议用通道解决,近期一个需求需要操作大型三维数组,业务逻辑上是可以划分多线程的(同一时段内操作仅局限在单一维度里进行),但是想了想不适合用管道做,因为需要大量的内存拷贝,如果用了的话也许拷贝本身浪费很多开销。
尝试按照 rust 标准书指导的在线程间共享 Arc ,但是得到提示 cannot borrow data in an Arc
as mutable ,传入线程闭包的 arc 对象无法被修改,必须要加一个 mutex ,但是一个疑惑 mutex 本身是互斥锁,本身各线程如果操作逻辑上不相关的数据时候理想情况是尽可能把锁优化掉,如果一定要加锁的话,现在又加了这种全局锁,那多线程操作又有什么意义呢?
1
Buges 2022-06-10 21:33:51 +08:00 via Android
最直接的就是锁的分片。比如读取和写入分开,数据不同部位分开。
不过对于并行计算问题,优先考虑 rayon 。https://github.com/rayon-rs/rayon 可能你手写写半天,rayon 一个 par_iter 就解决了。 |
2
Richard14 OP @Buges 不同部位分开以后感觉没必要上锁了吧,rust 要求下还是一定要锁吗。另外 rayon 确实搜到很多技术博客里也推荐,大佬有什么推荐的入门文章么
|
3
Richard14 OP @Buges 另外我的代码里是普通地用循环实现的操作,而不是用迭代器,感觉 rayon 介绍里那个神奇的 par_iter 用不上
|
4
Buges 2022-06-10 22:00:18 +08:00 via Android
@Richard14 Rust 里 Mutex 是一种线程安全的 interior mutability 容器,即可以通过对容器本身的只读访问获得容器内对象的读写访问。
不同部位分开锁就是 Mutex<Vec<T>>和 Vec<Mutex<T>>的区别。 rayon 本身就是设计的简单易用的库,直接看文档就行了。iter 可以配合 map/filter/reduce 及各种 combinator ,很多情况下比手写循环更方便,而且可读性要好的多。 |
5
greygoo 2022-06-14 15:41:45 +08:00 via Android
不用 Arc ,如果不同部分可以分开的话把原切片分成若干个&mut []然后 move 进每个线程里面就可以了
|
6
my3157 2022-06-14 19:08:26 +08:00
UnsafeCell 包一层, 实现内部可变性, 内部按需实现锁的粒度
|