Rust
thread::spawn
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 here
Because 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()); // true
Threads that aren't joined are terminated together with the program when the main thread ends.
Exercise 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.
Show example 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);
}
Test yourself
-
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
Show answer
The thread may outlive v; move or thread::scope is needed — E0373: closure may outlive the current function. The compiler suggests adding move.
-
Scoped thread
let toplam = thread::____(|s| {
let h = s.spawn(|| a.iter().sum::<i32>());
h.join().unwrap()
});
Show answer
let toplam = thread::scope(|s| {
let h = s.spawn(|| a.iter().sum::<i32>());
h.join().unwrap()
});
-
Tool and property
- thread::spawn
- Needs a 'static closure
- thread::scope
- Allows borrowing
- h.join()
- Waits for the end
- join() → Err
- The thread panicked
Next lesson: Mutex<T>