What am I using to share an object with many threads and a single author in Rust?

What is the correct approach to share a shared object between many threads when the object can sometimes be written by the same owner?

I tried to create one object object Configuration

with multiple methods to get and set configuration keys. I would like to channel this to other threads where config items can be read. There would be bonus points if they could be written and read by everyone.

I found a Reddit thread that talks about Rc

and RefCell

; will it be correct? I think this would prevent me from borrowing an object consistently multiple times and still mutating it.

+3


source to share


1 answer


Rust has a built-in concurrency primitive for just this task called RwLock

. Together with Arc

it, you can use it to implement what you want:

use std::sync::{Arc, RwLock};
use std::sync::mpsc;
use std::thread;

const N: usize = 12;

let shared_data = Arc::new(RwLock::new(Vec::new()));
let (finished_tx, finished_rx) = mpsc::channel();

for i in 0..N {
    let shared_data = shared_data.clone();
    let finished_tx = finished_tx.clone();
    if i % 4 == 0 {
        thread::spawn(move || {
            let mut guard = shared_data.write().expect("Unable to lock");
            guard.push(i);
            finished_tx.send(()).expect("Unable to send");
        });
    } else {
        thread::spawn(move || {
            let guard = shared_data.read().expect("Unable to lock");
            println!("From {}: {:?}", i, *guard);
            finished_tx.send(()).expect("Unable to send");
        });
    }
}

// wait until everything done
for _ in 0..N {
    let _ = finished_rx.recv();
}

println!("Done");

      



This example is very silly, but it demonstrates what RwLock

is and how to use it.

Also note that Rc

and RefCell

/ are Cell

not suitable in a multi-threaded environment because they are not synchronized properly. Rust won't even let you use them with thread::spawn()

. To exchange data between threads, you must use Arc

, and to exchange mutable data, you must additionally use one of the synchronization primitives, for example RwLock

or Mutex

.

+9


source







All Articles