如何使用没有作用域的RwLocks?

时间:2015-05-07 04:58:23

标签: rust

我试图在不使用作用域线程的情况下在多个线程中共享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;
}

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;
}