1/6

A channel moves ownership between threads. mpsc is multi-producer, single-consumer: clone the sender as many times as you need, keep one receiver.

let (tx, rx) = mpsc::channel::<u64>();
for id in 0..3 {
    let tx = tx.clone();
    thread::spawn(move || { tx.send(id).unwrap(); });
}
drop(tx);                       // drop the original, or rx never ends
for value in rx { ... }

That drop(tx) is the detail people miss. The receiver's iterator ends when every sender is gone — and the original tx in main is one of them.