l3u*_*fly 10 multithreading rust
我正在尝试将只读数据的“视图”发送到另一个线程进行处理。基本上主线程确实工作,不断更新一组数据。每当发生更新时,主线程应该将更新的数据发送到其他线程,在那里它们将以只读方式处理它。我不想复制数据,因为它可能非常大。(无论如何,主线程还在内存中保留数据的“缓存”。)
我可以用 来实现这一点Arc<RwLock<T>>,其中T是我的数据结构。
但是,没有什么可以阻止侧线程更新数据。侧线程可以简单地调用lock()和写入数据。
我的问题是,是否存在类似于RwLock它的所有者/创建者具有唯一写入访问权限,但所有其他实例都具有只读访问权限的情况?这样,我将在编译时检查可能通过侧线程意外更新数据而发生的任何逻辑错误。
关于这些问题:
上述问题建议用Arc<Mutex<T>>or来解决Arc<RwLock<T>>,这都可以。但它仍然不能只执行一个编写者的编译时操作。
另外:crossbeamorrayon的作用域线程在这里没有帮助,因为我希望我的副线程比我的主线程寿命更长。
Ibr*_*med 12
Arc<RwLock<T>>您可以通过只读包装器创建仅公开克隆的包装器类型:
mod shared {
use std::sync::{Arc, LockResult, RwLock, RwLockReadGuard, RwLockWriteGuard};
pub struct Lock<T> {
inner: Arc<RwLock<T>>,
}
impl<T> Lock<T> {
pub fn new(val: T) -> Self {
Self {
inner: Arc::new(RwLock::new(val)),
}
}
pub fn write(&self) -> LockResult<RwLockWriteGuard<'_, T>> {
self.inner.write()
}
pub fn read(&self) -> LockResult<RwLockReadGuard<'_, T>> {
self.inner.read()
}
pub fn read_only(&self) -> ReadOnly<T> {
ReadOnly {
inner: self.inner.clone(),
}
}
}
pub struct ReadOnly<T> {
inner: Arc<RwLock<T>>,
}
impl<T> ReadOnly<T> {
pub fn read(&self) -> LockResult<RwLockReadGuard<'_, T>> {
self.inner.read()
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以将值的只读版本传递给生成的线程,并继续在主线程中写入:
fn main() {
let val = shared::Lock::new(String::new());
for _ in 0..10 {
let view = val.read_only();
std::thread::spawn(move || {
// view.write().unwrap().push_str("...");
// ERROR: no method named `write` found for struct `ReadOnly` in the current scope
println!("{}", view.read().unwrap());
});
}
val.write().unwrap().push_str("...");
println!("{}", val.read().unwrap());
}
Run Code Online (Sandbox Code Playgroud)