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_");
}
  • Altere o tamanho do canal para 3 e veja como isso afeta a execução.

  • No geral, a interface Ă© semelhante aos canais sync vistos na aula da manhĂŁ.

  • Tente remover a chamada std::mem::drop. O que acontece? Por quĂȘ?

  • O crate Flume tem canais que implementam tanto sync quanto async send e recv. 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 async preferĂ­vel Ă© a capacidade de combinĂĄ-los com outras futures para combinĂĄ-los e criar um fluxo de controle complexo.