当我很少需要可变数据时,如何在多个线程之间共享数据?
How do I share data between several threads when I need it mutable only rarely?
我有一些 T
类型的数据,它既不实现 Copy
也不实现 Clone
。
- 如果我想在多个线程之间不可变地共享我的数据,我将使用
Arc<T>
。
- 如果我想可变地共享它,我将使用
Arc<Mutex<T>>
。
如果我想先可变地共享它,然后在循环中不可变地共享它怎么办?所以:
- 我无法使用
Arc<T>
或 Arc<Mutex<Arc<T>>>
,因为我无法更改 "mutable" 线程中的数据。
- 我可以使用
Arc<Mutex<T>>
,但我必须在每个 "immutable" 线程中 lock()
它才能达到 T
,失去并行性。
- 变异完成后无法复制数据,因为代价高昂(或者没有办法实现
Clone
)
那么正确有效的解决方法是什么?
std::sync::RwLock
是我要找的,谢谢@Shepmaster!
对于某些用例(例如缓存),Arc<Mutex<Arc<T>>>
是一个有趣的解决方案。
与RwLock
的主要区别:你可以在不保持读锁的情况下获取并使用它。
fn get<T>(mutex: &Arc<Mutex<Arc<T>>>) -> Arc<T> {
mutex.lock().unwrap().clone()
}
我有一些 T
类型的数据,它既不实现 Copy
也不实现 Clone
。
- 如果我想在多个线程之间不可变地共享我的数据,我将使用
Arc<T>
。 - 如果我想可变地共享它,我将使用
Arc<Mutex<T>>
。
如果我想先可变地共享它,然后在循环中不可变地共享它怎么办?所以:
- 我无法使用
Arc<T>
或Arc<Mutex<Arc<T>>>
,因为我无法更改 "mutable" 线程中的数据。 - 我可以使用
Arc<Mutex<T>>
,但我必须在每个 "immutable" 线程中lock()
它才能达到T
,失去并行性。 - 变异完成后无法复制数据,因为代价高昂(或者没有办法实现
Clone
)
那么正确有效的解决方法是什么?
std::sync::RwLock
是我要找的,谢谢@Shepmaster!
对于某些用例(例如缓存),Arc<Mutex<Arc<T>>>
是一个有趣的解决方案。
与RwLock
的主要区别:你可以在不保持读锁的情况下获取并使用它。
fn get<T>(mutex: &Arc<Mutex<Arc<T>>>) -> Arc<T> {
mutex.lock().unwrap().clone()
}