Course contentsShow
← Rust
Lesson 297 of 1,9103. Borrowing and ReferencesFree lesson

Scoped Threading for References

Use scoped threads to safely pass local references across thread boundaries.

In this lesson, you will learn how to safely share local data with threads by using scoped threading to bypass the strict 'static lifetime requirement.

The Problem with Standard Threads

Normally, when you spawn a thread with std::thread::spawn, Rust requires that any data you pass into the thread must have a 'static lifetime. This is because the compiler cannot guarantee that the thread won't outlive the function that spawned it. If you try to pass a reference to a local variable (like a slice or a stack-allocated integer) into a standard thread, the compiler will stop you: it knows the variable might be dropped while the thread is still trying to read it.

The Scoped Solution

Scoped threads provide a way to guarantee that all spawned threads will finish before the scope ends. Because the compiler can prove that the threads cannot outlive their parent, it is safe to allow those threads to borrow local data.

We use std::thread::scope to create this boundary. Inside the scope, you can reference local variables directly without needing to move them or wrap them in an Arc.

fn main() {
    let numbers = vec![1, 2, 3];

    // Create a scope. All threads here must finish before the block ends.
    std::thread::scope(|s| {
        s.spawn(|| {
            // We can safely borrow 'numbers' here!
            // No 'static lifetime needed.
            println!("I am borrowing the list: {:?}", numbers);
        });
    });

    // The scope has ended, so we know the thread is done. 
    // It is now safe to continue using 'numbers' here.
}

Why This Matters

By using std::thread::scope, you eliminate the need for costly synchronization primitives or cloning data. If you have a large buffer or a complex data structure on your stack, you can let multiple threads read it simultaneously without paying the performance penalty of moving or copying that data into each thread. It turns a lifetime error into a clean, localized concurrency pattern.

Key Takeaway: Scoped threads allow you to share local references across threads because the scope guarantees the threads finish before the referenced data is dropped.