A thread is an independent sequence of instructions executed within a process. Each thread has its own stack, while threads in the same process share memory and other resources. That makes threads useful for concurrent work, but access to shared resources needs synchronization to prevent race conditions and data corruption. section 7.5.1 section 9.2.1
Concurrency does not guarantee immediate execution:
- On one CPU core, the OS switches between threads so each can make progress without running simultaneously. section 9.2.1
- On different cores, threads can run in parallel. section 7.5.1
- A ready thread still waits for the OS to schedule it. For low-latency work, avoid creating too many competing threads; CPU affinity can restrict application threads to specific CPUs. section 7.5.1
A waiting request
A network request cannot be processed until the OS runs the thread that handles it. This delay can matter even when the thread has no application work ahead of the request. section 7.5.1
Figure 9.2 The OS runs multiple threads at the same time (but not simultaneously) on a single CPU core by context-switching between them. In this example, every thread is run for exactly 4 milliseconds, and then the OS switches to another thread. In real-world systems, a thread might block to wait for I/O, for example, causing the OS to switch to another thread more quickly.
Three threads take turns on one core in illustrative four-millisecond intervals. Real scheduling is more complex, and a thread waiting for I/O may yield sooner. section 9.2.1
fn main() {
let mut threads = vec![];
for i in 0..10 {
let t = std::thread::spawn(move || {
println!("Hello from thread {}", i);
});
threads.push(t);
}
for t in threads {
t.join().unwrap();
}
}
Rust’s std::thread::spawn() starts work in a closure and returns a handle; the example retains ten handles and joins each thread. section 9.2.1











