RustArena

Step 1 of 7

Spawning a thread and joining it

Every program so far has done one thing at a time, top to bottom. A thread is an independent line of execution inside your program: it has its own place in the code and its own local variables, and it runs alongside the others. Every program starts with one, the main thread. std::thread::spawn starts another.

Two words you'll hear a lot:

Threads give you both: the operating system runs them on as many cores as it has. Teams use threads to put every core to work on heavy jobs (resizing images, crunching log files, compressing backups), or to keep one part of a program responsive while another part waits.

use std::thread;

fn main() {
    let handle = thread::spawn(|| {
        let mut total: u64 = 0;
        for n in 1..=1_000 {
            total += n;
        }
        total
    });

    println!("main thread keeps going");
    let total = handle.join().unwrap();
    println!("the worker computed {total}");
}
main thread keeps going
the worker computed 500500

Piece by piece:

Threads run in an unpredictable order

If two threads both print, you can't know which line comes first. The operating system's scheduler decides which thread runs on which core, and when, and the answer changes from run to run:

let handle = thread::spawn(|| println!("hello from the worker"));
println!("hello from main");
handle.join().unwrap();
// Sometimes "main" prints first, sometimes "worker". Both are correct.

That's why the examples and exercises in this module never print from inside a worker. Workers return their results, and the main thread prints them after join, in a fixed order. Tests at work are written the same way: output that changes between runs makes a flaky test.

When main ends, the program ends

When main returns, the whole process exits, and every thread still running is stopped mid-work. A worker you forgot to join may never finish (or never even start). join is how you wait for it.

Common mistakes

Your task

Fill in the blanks: start a thread with thread::spawn, then wait for it and take its result with join. The program should print word count: 10.

Challenge 2

A JoinHandle remembers the type its thread returns. Fill in that type in the annotation so the program compiles and prints max temperature: 31.

Challenge 3

Spawn two threads before joining either of them, so they can run at the same time:

Then join both and print:

even sum: 2550
multiples of 7: 14

Next: move closures: giving data to a thread