Async Channels
Several crates have support for asynchronous channels. For instance tokio:
// Copyright 2024 Google LLC
// SPDX-License-Identifier: Apache-2.0
use tokio::sync::mpsc;
async fn ping_handler(mut input: mpsc::Receiver<()>) {
let mut count: usize = 0;
while let Some(_) = input.recv().await {
count += 1;
println!("Received {count} pings so far.");
}
println!("ping_handler complete");
}
#[tokio::main]
async fn main() {
let (sender, receiver) = mpsc::channel(32);
let ping_handler_task = tokio::spawn(ping_handler(receiver));
for i in 0..10 {
sender.send(()).await.expect("Failed to send ping.");
println!("Sent {} pings so far.", i + 1);
}
drop(sender);
ping_handler_task.await.expect("Something went wrong in ping handler task.");
}
This slide should take about 8 minutes.
-
Change the channel size to
3and see how it affects the execution. -
Overall, the interface is similar to the
syncchannels as seen in the morning class. -
Try removing the
std::mem::dropcall. What happens? Why? -
The Flume crate has channels that implement both
syncandasyncsendandrecv. This can be convenient for complex applications with both IO and heavy CPU processing tasks. -
What makes working with
asyncchannels preferable is the ability to combine them with otherfutures to combine them and create complex control flow.