有关如何在 Rust 多线程内共享内存

2022-06-10 21:19:37 +08:00
 Richard14

本人小白。以往 rust 中多线程需求都能按照建议用通道解决,近期一个需求需要操作大型三维数组,业务逻辑上是可以划分多线程的(同一时段内操作仅局限在单一维度里进行),但是想了想不适合用管道做,因为需要大量的内存拷贝,如果用了的话也许拷贝本身浪费很多开销。

尝试按照 rust 标准书指导的在线程间共享 Arc ,但是得到提示 cannot borrow data in an Arc as mutable ,传入线程闭包的 arc 对象无法被修改,必须要加一个 mutex ,但是一个疑惑 mutex 本身是互斥锁,本身各线程如果操作逻辑上不相关的数据时候理想情况是尽可能把锁优化掉,如果一定要加锁的话,现在又加了这种全局锁,那多线程操作又有什么意义呢?

1718 次点击
所在节点    Rust
6 条回复
Buges
2022-06-10 21:33:51 +08:00
最直接的就是锁的分片。比如读取和写入分开,数据不同部位分开。
不过对于并行计算问题,优先考虑 rayon 。https://github.com/rayon-rs/rayon
可能你手写写半天,rayon 一个 par_iter 就解决了。
Richard14
2022-06-10 21:39:13 +08:00
@Buges 不同部位分开以后感觉没必要上锁了吧,rust 要求下还是一定要锁吗。另外 rayon 确实搜到很多技术博客里也推荐,大佬有什么推荐的入门文章么
Richard14
2022-06-10 21:41:58 +08:00
@Buges 另外我的代码里是普通地用循环实现的操作,而不是用迭代器,感觉 rayon 介绍里那个神奇的 par_iter 用不上
Buges
2022-06-10 22:00:18 +08:00
@Richard14 Rust 里 Mutex 是一种线程安全的 interior mutability 容器,即可以通过对容器本身的只读访问获得容器内对象的读写访问。
不同部位分开锁就是 Mutex<Vec<T>>和 Vec<Mutex<T>>的区别。
rayon 本身就是设计的简单易用的库,直接看文档就行了。iter 可以配合 map/filter/reduce 及各种 combinator ,很多情况下比手写循环更方便,而且可读性要好的多。
greygoo
2022-06-14 15:41:45 +08:00
不用 Arc ,如果不同部分可以分开的话把原切片分成若干个&mut []然后 move 进每个线程里面就可以了
my3157
2022-06-14 19:08:26 +08:00
UnsafeCell 包一层, 实现内部可变性, 内部按需实现锁的粒度

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/858804

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX