RUST / CHAPTER 13

Owned messages and thread completion

Advanced

Transfer data deliberately and wait for concurrent results.

By the end of this chapter

  • Move owned data into a thread
  • Use channels for message transfer
  • Distinguish spawning from joining

The idea

A spawned thread can outlive the function that starts it, so data captured by its closure must satisfy the thread’s lifetime and transfer requirements. A move closure takes ownership of captured values as required, which is useful when a worker should own its input. Ownership transfer does not duplicate the original value. Some types are not safe to transfer or share across threads, and Rust’s Send and Sync traits express these boundaries.

A join handle allows the caller to wait for a worker and inspect whether it panicked. Channels transfer messages between producers and consumers; receiving can block until data arrives or disconnection is known. Design completion and failure paths so the receiver is not left waiting for a sender that will never send. Deterministic examples should synchronize explicitly instead of guessing which thread prints first.

Rust example
use std::thread;
fn main(){let xs=vec![2,4,6];let worker=thread::spawn(move || xs.into_iter().sum::<i32>());let total=worker.join().unwrap();println!("{}",total);}
Result
12

The worker owns the vector, and main prints only after joining and obtaining its completed result.

Try it yourself

Move a vector into a worker that counts positives, then return and join its result.

Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.

CHECK YOUR UNDERSTANDING

Chapter checkpoint

What does joining the worker establish before the following statement executes?