RwLock<T>
- Rust course
- Advanced
- Lesson 15/81
- 4 min
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
use std::sync::{Arc, RwLock};
use std::thread;
fn main() {
// buraya yaz
}Sample solution
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
kayit.____().unwrap().push(String::from("açılış"));
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 |