如何在不使用scoped的情况下使用RwLock?

5
我正在尝试在多个线程之间共享RwLock,而不使用scoped线程,但我无法弄清楚如何正确处理生命周期。我认为这是可能的(否则RwLock有什么意义呢?),但我找不到任何示例。
这里有一个玩具示例,我想要实现的内容。任何建议都将不胜感激。 此代码的Rust Playpen
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个回答

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接