liveBook · Manning

Thread safety

As explained in Code Like a Pro in Rust

Thread safety is the property that concurrent access to a value or operation preserves its correctness without data races or invalid state transitions.

Thread safety preserves correctness when concurrent threads access shared state. Rust enforces it through Send and Sync, while Arc, atomic types, Mutex, and RwLock provide practical building blocks. section 6.5

For parallel tests and global state:

  • Replace simple shared counters with an atomic integer and an explicit memory ordering. section 6.5
  • Use Arc when ownership must cross threads or multiple threads must share the same value. section 6.5
  • Use Mutex or RwLock when compound mutable state requires locking rather than atomic operations. section 6.5
  • Initialize non-constant global state lazily instead of constructing it directly in a static. section 6.5

Safe global test counter

A lazy_static AtomicI32 can be shared across parallel tests; each test calls fetch_add with Ordering::SeqCst. A Mutex<i32> instead serializes access through a lock guard. section 6.5

#[cfg(test)]
mod tests {
    use lazy_static::lazy_static;
    use std::sync::atomic::{AtomicI32, Ordering};
    use std::sync::Arc;
    lazy_static! {                                                        #1
        static ref COUNT: Arc<AtomicI32> = Arc::new(AtomicI32::new(0));   #2
    }
 
    #[test]
    fn test_count() {
        let count = Arc::clone(&COUNT);
        count.fetch_add(1, Ordering::SeqCst);
    }
}

Inspect the complete Arc-wrapped atomic counter using lazy initialization. section 6.5

How Code Like a Pro in Rust covers it

How deep it goes
Traces compiler errors through atomics, Arc, and lazy initialization, then demonstrates Mutex-based test serialization.
Examples
Uses a mutable static counter, atomic counter, Arc-wrapped counter, lazy_static expansion, and locked parallel tests.
What it assumes
Assumes familiarity with Rust threads and shared state while defining Send and Sync for this use case.
What you can do after
Apply Rust synchronization primitives to compile and run shared-state tests without data races or invalid static initialization.
How it connects
Connects Send and Sync with ownership, Arc, atomic integers, Mutex, RwLock, and lazy initialization.

Also explained in

Compare how 8 books explain thread safety →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Code Like a Pro in Rust. The section links point to the parts of the book it draws on.