Skip to main content

Threads and channels

`thread::spawn` starts an OS thread and returns a handle. The closure has to be `move`, because the thread may outlive the scope it was created in — the compiler will not let you borrow local data into it by accident.

A channel gives you message passing: clone the `Sender` for each worker, and the `Receiver` iterates until every sender has been dropped.

This is the 'share memory by communicating' style. No locks appear anywhere, and no data race is possible, because each value is moved to exactly one place.

Borrowing local data into a thread

use std::thread;

fn main() {
    let data = vec![1, 2, 3];
    thread::spawn(|| {
        println!("{data:?}"); // error[E0373]
    });
}

error[E0373]: closure may outlive the current function, but it borrows `data`

Add `move` so the closure takes ownership: `thread::spawn(move || ...)`. If several threads need it, wrap it in an `Arc`.

Run it and change it

The editor below is live: edit anything and the real compiler output updates by itself.

Your Rust