Canais Assíncronos
Vários crates têm suporte para canais assíncronos. Por exemplo, tokio:
use tokio::sync::mpsc::{self, Receiver};
async fn ping_handler(mut input: Receiver<()>) {
let mut count: usize = 0;
while let Some(_) = input.recv().await {
count += 1;
println!("Recebido {count} pings até agora.");
}
println!("_ping_handler_ completo");
}
#[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("Falha ao enviar _ping_");
println!("Enviado {} pings até agora.", i + 1);
}
drop(sender);
ping_handler_task.await.expect("Algo deu errado na tarefa do gerenciador de _ping_");
}
This slide should take about 8 minutes.
-
Altere o tamanho do canal para
3e veja como isso afeta a execução. -
No geral, a interface é semelhante aos canais
syncvistos na aula da manhã. -
Tente remover a chamada
std::mem::drop. O que acontece? Por quê? -
O crate Flume tem canais que implementam tanto
syncquantoasyncsenderecv. Isso pode ser conveniente para aplicações complexas com tarefas de processamento de I/O e CPU pesadas. -
O que torna o trabalho com canais
asyncpreferível é a capacidade de combiná-los com outras futures para combiná-los e criar um fluxo de controle complexo.