rwlock_pattern.md (2778B)
1 # RWLock Pattern 2 3 The RWLock (Readers-Writer Lock) pattern is a concurrency synchronization 4 primitive that allows multiple threads to read shared data simultaneously, but 5 requires exclusive access for any write operation. It's ideal for scenarios 6 where reads are frequent and writes are rare, as it avoids the unnecessary 7 serialization that a plain Mutex would impose. 8 9 ## Core Rules 10 11 - Multiple readers can hold the lock at the same time — reads are non-exclusive 12 13 - Only one writer can hold the lock at a time — writes are exclusive 14 15 - A write lock blocks all readers and other writers until it is released 16 17 - Once a writer is active, new readers must wait 18 19 ## Rust RwLock Example 20 21 Rust provides std::sync::RwLock<T> in its standard library. Here's a practical 22 example with multiple reader threads and one writer thread: 23 24 ```rust 25 use std::sync::{Arc, RwLock}; 26 use std::thread; 27 28 fn main() { 29 // Wrap data in Arc<RwLock<T>> for shared ownership across threads 30 let data = Arc::new(RwLock::new(0u32)); 31 32 // --- Writer thread: exclusive access --- 33 let data_writer = Arc::clone(&data); 34 let writer = thread::spawn(move || { 35 let mut w = data_writer.write().unwrap(); // blocks until no readers/writers 36 *w += 42; 37 println!("Writer set value to: {}", *w); 38 }); // write lock dropped here 39 40 writer.join().unwrap(); 41 42 // --- Multiple reader threads: concurrent access --- 43 let reader_handles: Vec<_> = (0..4).map(|i| { 44 let data_reader = Arc::clone(&data); 45 thread::spawn(move || { 46 let r = data_reader.read().unwrap(); // multiple readers can hold this simultaneously 47 println!("Reader {} sees value: {}", i, *r); 48 }) 49 }).collect(); 50 51 for handle in reader_handles { 52 handle.join().unwrap(); 53 } 54 } 55 ``` 56 57 ### Output (reader order may vary): 58 59 ```text 60 Writer set value to: 42 61 Reader 0 sees value: 42 62 Reader 2 sees value: 42 63 Reader 1 sees value: 42 64 Reader 3 sees value: 42 65 ``` 66 67 ## When to Use vs. Mutex 68 69 RwLock is only better than Mutex when you have many concurrent readers competing 70 at the same time. For a single reader or low concurrency, an uncontended RwLock 71 is no faster than a Mutex because readers still acquire the lock and update 72 internal state. A good rule of thumb: if your workload is read-heavy (e.g., 90%+ 73 reads) with rare writes, RwLock gives a meaningful throughput boost. 74 75 ## Watch Out: Lock Poisoning 76 77 In Rust, if a thread panics while holding a write lock, the RwLock becomes 78 poisoned. Subsequent calls to .read() or .write() will return an Err, which you 79 handle via .unwrap() or .into_inner(). This is a safety feature to prevent 80 access to potentially corrupt data. 81 82 [RWLock](https://dev-doc.rust-lang.org/beta/std/sync/struct.RwLock.html)