Асинхронные каналы
Несколько крейтов поддерживают асинхронные каналы. Например, 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.");
}
-
Измените размер канала на
3и посмотрите, как это повлияет на выполнение. -
В целом интерфейс похож на синхронные каналы, которые мы видели на утреннем занятии.
-
Попробуйте убрать вызов
std::mem::drop. Что произойдёт? Почему? -
Крейт Flume содержит каналы, которые реализуют и синхронные, и асинхронные
sendиrecv. Это может быть удобно в сложных приложениях с задачами и вводом-выводом, и тяжёлой процессорной обработкой. -
Работа с асинхронными каналами удобнее благодаря возможности комбинировать их с другими фьючерсами, чтобы создавать сложный поток управления.