Is a for loop iteration over a receiving end of a mpsc implicitly sleeping?

Hello,

I am following the Rust book and have a question on the following code.
I found a question on the topic Iterating through Channel
but the answer does not explain what exactly happens.
How does the for loop iteration know when to wait for another input in rx and when to exit the loop?

use std::sync::mpsc;
use std::thread;
use std::time::Duration;

fn main() {
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        let vals = vec![
            String::from("hi"),
            String::from("from"),
            String::from("the"),
            String::from("thread"),
        ];

        for val in vals {
            tx.send(val).unwrap();
            thread::sleep(Duration::from_secs(1));
        }
    });

    for received in rx {
        println!("Got: {received}");
    }
}

In addition to information about the items, the channel also communicates whether one side has been dropped. So in the spawned thread, after the end of the closure, tx is dropped (because it was moved into the closure), and rx reads that and returns None in the iterator.

1 Like

It doesn't. It's the channel that blocks when it's empty while it's being read from, and if that's blocked, effectively the thread as a whole (as well as the for-loop in it) gets blocked.

1 Like

To add to what @jjpe said, the for loop is creating an iterator from the channel, and calling the Iterator::next function. The iterator is implemented for the channel's Iter struct and its behavior is documented there:

This iterator will block whenever next is called, waiting for a new message, and None will be returned when the corresponding channel has hung up.