thread::spawn
- Rust course
- Advanced
- Lesson 13/81
- 4 min
Spawn OS threads with std::thread::spawn.
thread::spawn
thread::spawn starts a new operating-system thread and returns a JoinHandle. The thread's closure must be 'static, so it can't borrow outside variables; it takes ownership with move. If borrowing is needed, scoped threads (thread::scope) are used:
let v = vec![1, 2, 3, 4];
let (a, b) = v.split_at(2);
let toplam = thread::scope(|s| {
let h1 = s.spawn(|| a.iter().sum::<i32>());
let h2 = s.spawn(|| b.iter().sum::<i32>());
h1.join().unwrap() + h2.join().unwrap()
}); // all threads end hereBecause scope guarantees that all threads inside finish before the scope ends, it allows borrowing local data.
join and panics
join waits until the thread finishes and gives its result inside a Result. If the thread panics, it returns Err; the panic doesn't spread to the main thread:
let h = thread::spawn(|| {
panic!("hata");
});
println!("{}", h.join().is_err()); // trueThreads that aren't joined are terminated together with the program when the main thread ends.
Practice Two halves
Split the vector vec![1, 2, 3, 4] in two with split_at(2). Inside thread::scope, sum each half on a separate thread, combine the results and print.
Starter code
use std::thread;
fn main() {
// buraya yaz
}Sample solution
use std::thread;
fn main() {
let v = vec![1, 2, 3, 4];
let (a, b) = v.split_at(2);
let toplam = thread::scope(|s| {
let h1 = s.spawn(|| a.iter().sum::<i32>());
let h2 = s.spawn(|| b.iter().sum::<i32>());
h1.join().unwrap() + h2.join().unwrap()
});
println!("{}", toplam);
}Expected output
10
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Why doesn't <code>thread::spawn(|| println!("{:?}", v))</code> compile? (<code>v</code> is a local Vec)
- println! doesn't work in threads
- A Vec can't be shared
- It compiles
- The thread may outlive v; move or thread::scope is needed Correct answer
Explanation: E0373: closure may outlive the current function. The compiler suggests adding move.
2 Scoped thread
let toplam = thread::____(|s| {
let h = s.spawn(|| a.iter().sum::<i32>());
h.join().unwrap()
});
let toplam = thread::scope(|s| {
let h = s.spawn(|| a.iter().sum::<i32>());
h.join().unwrap()
});
Explanation: thread::scope allows borrowing local data.
3 Tool and property
| Term | Meaning |
|---|---|
thread::spawn |
Needs a 'static closure |
thread::scope |
Allows borrowing |
h.join() |
Waits for the end |
join() → Err |
The thread panicked |