Threads, ownership and joining
Threads, ownership and joining
A school tool can compute a subtotal on a worker thread while main coordinates the report. A thread is an independently scheduled execution path. Ownership determines what data the worker may keep, while joining waits for it to finish and retrieves its result.
What you’ll learn
- Transfer owned inputs to a worker and retrieve its result.
- Distinguish thread creation from completion at join.
Threads, ownership and joining in action
Move marks to worker
The worker owns the vector and sums it to 240.
Move marks to workerWorker computes 240
Main waits at join before receiving that integer and printing it.
Worker computes 240Join before printing result
Main cannot reuse the moved marks binding; it can use the returned total.
Join before printing result
Threads, ownership and joining explained
thread::spawn accepts a closure that may outlive the calling scope. A move closure transfers the captured vector into the worker. join returns a Result because the worker may panic. The example prints only after joining, so its displayed order does not depend on which thread the scheduler runs first.
Connect this idea with ownership, moves and cleanup and channels, arc and mutex.
Work through the Rust program
Save the complete source as main.rs in the Rust environment. No standard input is needed.
Rust 2024 · complete program
use std::thread;
fn main() {
let marks = vec![70, 80, 90];
let worker = thread::spawn(move || marks.into_iter().sum::<i32>());
let total = worker.join().expect("worker should complete");
println!("Total: {total}");
}Expected output
Total: 240Follow the execution
The worker owns the vector and sums it to 240. Main waits at join before receiving that integer and printing it. Main cannot reuse the moved marks binding; it can use the returned total.
Try the complete program in the Rust compiler. For tests, Cargo commands and local files, use the specified local environment.
Try a small variation
Your task: Why is the final print after join important?
Rust 2024 · complete program
use std::thread;
fn main() {
let marks = vec![70, 80, 90];
let worker = thread::spawn(move || marks.into_iter().sum::<i32>());
let total = worker.join().expect("worker should complete");
println!("Total: {total}");
}Worked answer
It waits until the worker has produced the result. Starting a thread alone does not guarantee it has completed before the next instruction in main.
Mistakes and limits to recognize
Thread creation has overhead and does not guarantee a speedup. Scoped threads can borrow suitable data while the scope ensures they finish. A panic in a worker is reported through join; real applications should choose a recovery policy rather than automatically expecting success.
Check your understanding
Take the idea into your next program
It waits until the worker has produced the result. Starting a thread alone does not guarantee it has completed before the next instruction in main. Thread creation has overhead and does not guarantee a speedup.
Further reading: the official Rust Book on threads, ownership and joining.
Reaching the recap and completing the quizzes are separate milestones.