Guide

Channels

A channel lets threads talk by sending messages instead of sharing data.

mpsc channels

mpsc::channel() returns a pair: a sender (tx) and a receiver (rx). mpsc means "many producers, single consumer". You can have many senders, but only one receiver.

use std::sync::mpsc;use std::thread;let (tx, rx) = mpsc::channel();thread::spawn(move || {    tx.send(7).unwrap();});println!("{}", rx.recv().unwrap()); // 7

send moves the value

tx.send(v) moves v into the channel. The receiver becomes the new owner. Using v after sending is error E0382. Copy types like i32 are copied, so they stay usable.

let s = String::from("hi");tx.send(s).unwrap();// println!("{s}"); // error E0382

Receiving

rx.recv() waits until a message arrives. It returns Err once every sender is gone and the channel is empty.

A for loop reads messages one by one, in the order they were sent. The loop ends when all senders have been dropped.

drop(tx);for msg in rx {    println!("{msg}");}

If a sender is still alive, the loop keeps waiting for more.

Many producers

Clone the sender to give each thread its own:

for id in 0..3 {    let tx = tx.clone();    thread::spawn(move || {        tx.send(id).unwrap();    });}drop(tx); // drop the original too

Messages from different threads can arrive in any order. To get a fixed order, collect them in a Vec and call v.sort(), which puts the Vec in order from small to big.

Remember

  • send moves the value; use it after and you get E0382.
  • recv waits for one message.
  • for msg in rx ends only when every sender is dropped.
  • Clone tx for more producers; the receiver can't be cloned.