Concurrency lets a program carry out multiple tasks over overlapping periods. It does not require multiple CPU cores: on one core, the operating system can block a thread waiting for memory or I/O and schedule it again when the data is available. Parallelism is the related use of multiple physical cores at the same time. section 10.0
Rust’s promise of “fearless concurrency” rests on its emphasis on safety across independent threads. Threads can otherwise interfere with one another when a programmer makes a serious mistake. Rust has no global interpreter lock limiting a thread’s speed, but safety does not remove the need to choose how tasks run and communicate. section 1.7.2 section 1.12
Listing 1.4 Example of Rust preventing a race condition
use std::thread; #1
fn main() {
let mut data = 100;
thread::spawn(|| { data = 500; }); #2
thread::spawn(|| { data = 1000; }); #2
println!("{}", data);
}
Two spawned threads attempt to change the same local variable. The example is rejected rather than allowed to become a race condition. section 1.6.1
The unit used to carry out a task affects both isolation and cost:
- Threads in one process share an address space; processes cannot inspect one another’s memory. section 10.5
- Greater isolation can prevent some failures from spreading, but generally adds runtime overhead. Isolation is not absolute: tasks still need input and output. section 10.5
- Coroutines within a blocked thread cannot progress while that thread waits for console output. section 10.5
Too many CPU-intensive threads
A comparison of sleeping threads and threads running spin loops shows why spawning more threads is not automatically faster. On the six-core CPU used for the measurement, CPU-intensive performance degraded quickly once the thread count exceeded the physical core count. section 10.2.4
Figure 10.3 Comparing the time taken to wait for 20m using the sleep strategy (circles) versus the spin lock strategy (plus symbols). This chart shows the differences that occur as the number of threads exceeds the number of CPU cores (6).
The chart makes the change at six physical cores visible when competing threads outnumber cores. section 10.2.4
Closures provide syntax used by Rust’s concurrency APIs. From there, practical tools include spawning threads, channels and message passing, task queues, and the standard library alongside the crossbeam and rayon crates. Using these tools is a different goal from implementing a concurrency crate. section 10.0






















