CodeBlanks Logo Icon CodeBlanks

RwLock<T>

Use a many-reader single-writer lock with RwLock<T>.

RwLock<T>

RwLock<T> is the cross-thread version of the borrowing rules: at any time many readers (read()) or one writer (write()). For data read far more often than written (settings, caches), it's more efficient than a Mutex:

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

let kayit = Arc::new(RwLock::new(Vec::new()));
kayit.write().unwrap().push(String::from("açılış"));
let adet = kayit.read().unwrap().len();

Readers don't block each other; a writer waits for all readers to finish.

Reader threads

Each reader reads with its own Arc copy; the read guard is held briefly inside the thread:

let tutucular: Vec<_> = (0..3)
    .map(|_| {
        let k = Arc::clone(&kayit);
        thread::spawn(move || k.read().unwrap().len())
    })
    .collect();
let uzunluklar: Vec<usize> = tutucular.into_iter().map(|h| h.join().unwrap()).collect();

Practice Many readers

Create an Arc<RwLock<Vec<String>>> and add two records with write. Start three reader threads; let each return the length with read. Collect the results in order and print them.

Starter code

main.rs
use std::sync::{Arc, RwLock};
use std::thread;

fn main() {
    // buraya yaz
}

Sample solution

main.rs
use std::sync::{Arc, RwLock};
use std::thread;

fn main() {
    let kayit = Arc::new(RwLock::new(Vec::new()));
    kayit.write().unwrap().push(String::from("açılış"));
    kayit.write().unwrap().push(String::from("giriş"));
    let tutucular: Vec<_> = (0..3)
        .map(|_| {
            let k = Arc::clone(&kayit);
            thread::spawn(move || k.read().unwrap().len())
        })
        .collect();
    let uzunluklar: Vec<usize> = tutucular.into_iter().map(|h| h.join().unwrap()).collect();
    println!("{:?}", uzunluklar);
}

Expected output

[2, 2, 2]

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 If writes are almost as frequent as reads, which is usually better?

  • Cell
  • Mutex; RwLock's extra bookkeeping cancels the gain Correct answer
  • RwLock always
  • Neither can be used

Explanation: RwLock must track the reader count; if reads don't dominate, a simple Mutex is faster. Don't decide without measuring.

2 Write lock

Question
kayit.____().unwrap().push(String::from("açılış"));
Answer
kayit.write().unwrap().push(String::from("açılış"));

Explanation: RwLock::write gives exclusive write access.

3 Method and access

Term Meaning
read() Shared read
write() Exclusive write
Mutex::lock() Every access exclusive
try_read() Try without waiting

All lessons in Advanced