Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Closing a Channel, like in Go

Tags:

rust

channel

Does Rust have a way of "closing" a channel, similar to what is available in Go?

The idea is to iterate over the channel (receive continually) until the channel indicates that it will not produce any more values.

use std::sync::{Arc, Mutex};
use std::thread;
use std::sync::mpsc;

fn main() {
    let data = Arc::new(Mutex::new(0u32));
    let (tx, rx) = mpsc::channel::<u32>();
    {
        let (data, tx) = (data.clone(), tx.clone());
        thread::spawn(move || {
            for _ in 0..10 {
                let mut data = data.lock().unwrap();
                *data += 1;
                tx.send(*data).unwrap();
            }
            // *** How could I close the channel here, to signal the work is done?
        });
    }

    // *** How can I detect a closed channel here? Pattern matching?
    for _ in 0..10 {
        let x = rx.recv().unwrap();
        println!("{}", x);
    }
}
like image 750
jocull Avatar asked Jul 13 '15 19:07

jocull


People also ask

Do I need to close channels in Go?

It's OK to leave a Go channel open forever and never close it. When the channel is no longer used, it will be garbage collected. Note that it is only necessary to close a channel if the receiver is looking for a close. Closing the channel is a control signal on the channel indicating that no more data follows.

When should I close a channel?

The Channel Closing Principle One general principle of using Go channels is don't close a channel from the receiver side and don't close a channel if the channel has multiple concurrent senders. In other words, we should only close a channel in a sender goroutine if the sender is the only sender of the channel.

Can you read from a closed channel Golang?

The value read from a closed channel will be the zero value of the channel's type. For example, if the channel is an int channel, then the value received from a closed channel will be 0 . The for range form of the for loop can be used to receive values from a channel until it is closed.


1 Answers

The channel is closed when all Senders have dropped. In your code you clone and give one each to each thread, these drop as they should when the threads end. The last sender is in the main thread, and you should drop it as soon as all the threads have been spawned: drop(tx).

Finally, the easiest way to receive is this, after the drop(tx).

for elt in rx {
    /* */
}

This loop ends when the channel is closed.

like image 195
bluss Avatar answered Sep 24 '22 00:09

bluss