我试图在不使用范围线程的情况下在多个线程中共享一个RwLock,但我无法弄清楚如何使生命周期正确.我认为这是可能的(否则RwLocks的重点是什么?)但是我找不到它的任何例子.
这是我想要完成的一个玩具示例.任何意见,将不胜感激. 这个代码的防锈围栏
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;
}
Run Code Online (Sandbox Code Playgroud)
&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;
}
Run Code Online (Sandbox Code Playgroud)