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);
}
}
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With