Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use RwLocks without scoped?

Tags:

rust

I'm trying to share a RwLock amongst several threads without using scoped threads but I can't figure out how to get the lifetimes correct. I assume that this is possible (what's the point of RwLocks otherwise?) but I can't find any examples of it.

Here is a toy example of what I'm trying to accomplish. Any advice would be appreciated. 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;
}
like image 733
user1056805 Avatar asked May 07 '15 04:05

user1056805


1 Answers

&mut references are not safe to send to a non-scoped thread, because the thread may still run after the referenced data has been deallocated. Furthermore, after helper returns, the main thread would still be able to mutate stuff, and the spawned thread would also be able to mutate stuff indirectly, which is not allowed in Rust (there can only be one mutable alias for a variable).

Instead, the RwLock should own the data, rather than borrow it. This means helper should receive a Stuff rather than a &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;
}
like image 135
Francis Gagné Avatar answered Nov 15 '22 08:11

Francis Gagné