A blocking operation stops the current thread while it waits for an external activity to finish, such as reading a large file or querying a database. In synchronous code, work after that operation cannot continue until the wait ends. section 10.1
Two simulated file reads
A Rust program calls two file-reading functions in sequence. Each uses `std::thread::sleep` to simulate a delay: four seconds for the first read and two for the second. Because `main` waits for each call to return, the delays add up to six seconds. The functions simulate file reads; they do not perform actual file I/O. section 10.2
use std::thread;
use std::thread::sleep;
use std::time::Duration;
fn main() {
println!("Hello before reading file!");
let handle1 = thread::spawn(|| { #1
let file1_contents = read_from_file1();
println!("{:?}", file1_contents);
});
let handle2 = thread::spawn(|| { #2
let file2_contents = read_from_file2();
println!("{:?}", file2_contents);
});
handle1.join().unwrap(); #3
handle2.join().unwrap(); #4
}
// function that simulates reading from a file
fn read_from_file1() -> String {
sleep(Duration::new(4, –));
String::from("Hello, there from file 1")
}
// function that simulates reading from a file
fn read_from_file2() -> String {
sleep(Duration::new(2, –));
String::from("Hello, there from file 2")
}
The revised program starts each simulated read with `thread::spawn`, then uses `join` to wait for both threads. The sleeps still block their respective threads, but the reads can proceed concurrently. section 10.2
Async processing takes a different scheduling approach: when a task waits for I/O, a runtime such as Tokio can schedule another task and later resume the first. This differs from `std::thread::sleep`, which blocks its current thread even when called inside an `async fn`. Choose between synchronous execution, threads, and async processing according to the work being done and where it waits. section 10.1 section 10.2








