liveBook · Manning

Scoped thread

As explained in Learn Rust in a Month of Lunches

A scoped thread is a thread whose lifetime is bounded by a lexical scope, allowing it to borrow non-'static data and requiring it to finish before the scope ends.

A scoped thread runs only inside a lexical scope. Because the scope waits for its threads to finish, they can borrow non-'static data instead of taking ownership of everything they use. section 12.4

use std::thread;
 
fn main() {
    thread::scope(|s| {   #1
        s.spawn(|| {
                          #2
        });
        s.spawn(|| {
                          #2
        });#
    });                   #3
}

Start with thread::scope, then spawn threads through the scope handle. The closing brace marks the boundary beyond which those threads cannot continue. section 12.4

Scoped threads simplify ordinary thread code in several ways:

  • Let threads borrow local values without requiring a 'static lifetime. section 12.4
  • Join threads automatically when the scope ends, so explicit .join() calls are unnecessary. section 12.4
  • Avoid Arc when shared data can be borrowed safely within the scope. section 12.4
  • Continue following Rust borrowing rules: multiple immutable borrows work, but simultaneous mutable access still needs coordination. section 12.4
  • Ensure every scoped thread eventually ends; an unfinished thread keeps its scope, and therefore the program, from ending. section 12.6

Sharing a mutable number

Two scoped threads can increment data protected by a Mutex without wrapping it in Arc. A second example borrows one mutable local from a single thread while both threads read another local immutably; the output order varies because the threads run concurrently. section 12.4

How Learn Rust in a Month of Lunches covers it

How deep it goes
Explains syntax, automatic joining, borrowing rules, synchronization, output variation, and termination constraints, but not thread internals.
Examples
Demonstrates thread::scope, automatic joining, shared Mutex updates, local borrows, variable output, and one thousand spawned threads.
What it assumes
Assumes familiarity with regular threads, .join(), borrowing, and Mutex while contrasting their requirements with scoped threads.
What you can do after
Build it from scratch with thread::scope and scoped spawn, then apply Rust borrowing rules to shared concurrent data.
How it connects
Connects scoped threads with thread spawning, lexical scope, borrowing, lifetimes, Mutex, Arc, and immutable or mutable references.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Rust in a Month of Lunches. The section links point to the parts of the book it draws on.