22.11 Summary
Rust offers robust and safe mechanisms for concurrent programming using OS threads, leveraging its ownership and type system to prevent data races at compile time—a significant advantage compared to C and C++. This chapter covered:
- Core Concepts: Differentiated concurrency (structure) from parallelism (execution), and processes (isolated) from threads (shared memory). Highlighted risks like race conditions and deadlocks.
- Compile-Time Safety: Explained how Rust’s ownership, borrowing, and the
Send
/Sync
marker traits prevent data races in safe code by enforcing strict access rules. - OS Threads (
std::thread
): Introducedthread::spawn
for creating threads,JoinHandle
for managing them (joining, getting results, panic handling),move
closures for transferring ownership, andBuilder
for configuration (name, stack size). Noted the'static
lifetime requirement forspawn
. - Data Sharing Primitives: Detailed mechanisms for safe shared access:
Arc<T>
: For thread-safe shared ownership (atomic reference counting).Mutex<T>
: For synchronized, exclusive mutable access (RAII guards).RwLock<T>
: For allowing concurrent readers or a single writer (RAII guards).Condvar
: For thread synchronization based on conditions, used withMutex
.- Atomic Types (
std::sync::atomic
): For lock-free atomic operations on primitives, requiring careful memory ordering.
- Scoped Threads (
std::thread::scope
): Showcased how scoped threads lift the'static
requirement, allowing threads to safely borrow data from their parent stack frame. - Message Passing (
std::sync::mpsc
): Presented channels (Sender
/Receiver
) as an alternative model based on transferring ownership of messages, avoiding direct shared state. Mentioned advanced channel crates (crossbeam-channel
). - Data Parallelism (
rayon
): Demonstrated how Rayon simplifies parallelizing computations over collections using parallel iterators (par_iter
,par_iter_mut
) and functions likerayon::join
, managing a work-stealing thread pool automatically. - SIMD (
std::arch
,std::simd
): Introduced SIMD as instruction-level parallelism for numerical tasks, covering auto-vectorization and explicit intrinsics (platform-specificstd::arch
vs. safer, experimental, portablestd::simd
). - C/C++ Comparison: Explicitly contrasted Rust’s compile-time data race prevention with the runtime risks and debugging challenges in C/C++.
Choosing the right concurrency model (OS threads for CPU-bound work, async tasks for I/O-bound work) depends on the application’s needs. Regardless of the model, Rust’s focus on safety aims to make concurrent programming more reliable and less error-prone than in traditional systems languages.