CodeBlanks Logo Icon CodeBlanks

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.

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

main.rs
use std::thread;

fn main() {
    // buraya yaz
}

Sample solution

main.rs
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

Question
let toplam = thread::____(|s| {
    let h = s.spawn(|| a.iter().sum::<i32>());
    h.join().unwrap()
});
Answer
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

All lessons in Advanced