Rust's standard library provides an implementation of channels. A channel is a general programming concept by which data is sent from one thread to another.
mpsc
Multiple producer, single consumer. The was the standard library implements channels means a channel can have multiple sending ends that produce values but only one receiving end that consumes those values.
send
Attempts to send a value on this channel.
The send method returns a Result<T, E> type, so if the receiver has already
been dropped and there’s nowhere to send a value, the send operation will return
an error.
use std::{sync::mpsc, thread, time::Duration};
fn main() {
let (tx, rx) = mpsc::channel();
let tx1 = tx.clone();
thread::spawn(move || {
let vals = vec![
String::from("hi"),
String::from("from"),
String::from("the"),
String::from("thread"),
];
for val in vals {
tx1.send(val).unwrap();
thread::sleep(Duration::from_secs(1));
}
});
thread::spawn(move || {
let vals = vec![
String::from("more"),
String::from("messages"),
String::from("for"),
String::from("you"),
];
for val in vals {
tx.send(val).unwrap();
thread::sleep(Duration::from_secs(1));
}
});
for received in rx {
println!("Got: {received}");
}
}
recv
Attempts to wait for a value on this receiver, returning an error if the corresponding channel has hung up.
If the corresponding Sender has disconnected, or it disconnects while
this call is blocking, this call will wake up and return Err to
indicate that no more messages can ever be received on this channel.
However, since channels are buffered, messages sent before the disconnect
will still be properly received.
try_recv
The try_recv method doesn't block, but will instead return a Result<T, E>
immediately: an Ok value holding a message if one is available and an Err value
if there aren’t any messages this time.
Using try_recv is useful if this thread has other work to do while waiting for
messages: we could write a loop that calls try_recv every so often, handles a
message if one is available, and otherwise does other work for a little while
until checking again.
ownership transference
If we attempt to use a value after we've passed a reference of it down a channel we will get a compiler error because we have no idea what state that value could be in now.