我试图在不使用作用域线程的情况下在多个线程中共享RwLock,但我无法弄清楚如何使生命周期正确。我认为这是可能的(否则RwLocks的意思是什么?)但我找不到任何例子。
这是我想要完成的一个玩具示例。任何意见,将不胜感激。 rust playpen for this code
use std::sync::{Arc, RwLock};
use std::thread;
struct Stuff {
x: i32
}
fn main() {
let mut stuff = Stuff{x: 5};
helper(&mut stuff);
println!("done");
}
fn helper(stuff: &mut Stuff){
let rwlock = RwLock::new(stuff);
let arc = Arc::new(rwlock);
let local_arc = arc.clone();
for _ in 0..10{
let my_rwlock = arc.clone();
thread::spawn(move || {
let reader = my_rwlock.read().unwrap();
// do some stuff
});
}
let mut writer = local_arc.write().unwrap();
writer.x += 1;
}
答案 0 :(得分:7)
&mut
引用是不安全的,因为在引用的数据被释放后,该线程仍然可以运行。此外,在helper
返回后,主线程仍然可以变异stuff
,并且生成的线程也可以间接地变异stuff
,这在Rust中是不允许的(那里)只能是变量的一个可变别名。
相反,RwLock
应该拥有数据,而不是借用它。这意味着helper
应该收到Stuff
而不是&mut Stuff
。
use std::sync::{Arc, RwLock};
use std::thread;
struct Stuff {
x: i32
}
fn main() {
let mut stuff = Stuff{x: 5};
helper(stuff);
println!("done");
}
fn helper(stuff: Stuff){
let rwlock = RwLock::new(stuff);
let arc = Arc::new(rwlock);
let local_arc = arc.clone();
for _ in 0..10{
let my_rwlock = arc.clone();
thread::spawn(move || {
let reader = my_rwlock.read().unwrap();
// do some stuff
});
}
let mut writer = local_arc.write().unwrap();
writer.x += 1;
}